From 859361a228258edf4821d9f5635825033eca78e8 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Thu, 2 Aug 2012 14:05:59 -0600 Subject: NVMe: Free cmdid on nvme_submit_bio error nvme_map_bio() is called after the cmdid is allocated, so we have to free the cmdid before returning from nvme_submit_bio() if nvme_map_bio() returned an error. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox --- drivers/block/nvme.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index 931769e133e5..954a61018dc2 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -237,7 +237,8 @@ static void *free_cmdid(struct nvme_queue *nvmeq, int cmdid, *fn = special_completion; return CMD_CTX_INVALID; } - *fn = info[cmdid].fn; + if (fn) + *fn = info[cmdid].fn; ctx = info[cmdid].ctx; info[cmdid].fn = special_completion; info[cmdid].ctx = CMD_CTX_COMPLETED; @@ -589,7 +590,7 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, result = nvme_map_bio(nvmeq->q_dmadev, iod, bio, dma_dir, psegs); if (result < 0) - goto free_iod; + goto free_cmdid; length = result; cmnd->rw.command_id = cmdid; @@ -609,6 +610,8 @@ static int nvme_submit_bio_queue(struct nvme_queue *nvmeq, struct nvme_ns *ns, return 0; + free_cmdid: + free_cmdid(nvmeq, cmdid, NULL); free_iod: nvme_free_iod(nvmeq->dev, iod); nomem: -- cgit v1.2.3 From 3295874b6074d749516d6decd43afad7bf6e38ff Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Mon, 20 Aug 2012 14:57:49 -0600 Subject: NVMe: End queued bio requests when freeing queue If the queue has bios queued on it when it is freed, bio_endio() must be called for them first. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox --- drivers/block/nvme.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index 954a61018dc2..af88635e44e4 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -909,6 +909,10 @@ static void nvme_free_queue(struct nvme_dev *dev, int qid) spin_lock_irq(&nvmeq->q_lock); nvme_cancel_ios(nvmeq, false); + while (bio_list_peek(&nvmeq->sq_cong)) { + struct bio *bio = bio_list_pop(&nvmeq->sq_cong); + bio_endio(bio, -EIO); + } spin_unlock_irq(&nvmeq->q_lock); irq_set_affinity_hint(vector, NULL); -- cgit v1.2.3 From f4f117f64baf8840d22266d518227b2a186d294b Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 21 Sep 2012 10:49:05 -0600 Subject: NVMe: Set result from user admin command The ioctl data structure includes space for the 'result' of the admin command to be returned; it just wasn't filled in. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox --- drivers/block/nvme.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index af88635e44e4..47c860454289 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -1237,12 +1237,17 @@ static int nvme_user_admin_cmd(struct nvme_dev *dev, if (length != cmd.data_len) status = -ENOMEM; else - status = nvme_submit_admin_cmd(dev, &c, NULL); + status = nvme_submit_admin_cmd(dev, &c, &cmd.result); if (cmd.data_len) { nvme_unmap_user_pages(dev, cmd.opcode & 1, iod); nvme_free_iod(dev, iod); } + + if (!status && copy_to_user(&ucmd->result, &cmd.result, + sizeof(cmd.result))) + status = -EFAULT; + return status; } -- cgit v1.2.3 From 08df1e05657fc6712e520e7c09cc6c86160ceb35 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Fri, 21 Sep 2012 10:52:13 -0600 Subject: NVMe: Add result to nvme_get_features nvme_get_features() was not returning the result. Add a parameter to return the result in (similar to nvme_set_features()) and change all callers. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox --- drivers/block/nvme.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index 47c860454289..c1d5444f0cb3 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -838,8 +838,8 @@ static int nvme_identify(struct nvme_dev *dev, unsigned nsid, unsigned cns, return nvme_submit_admin_cmd(dev, &c, NULL); } -static int nvme_get_features(struct nvme_dev *dev, unsigned fid, - unsigned nsid, dma_addr_t dma_addr) +static int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, + dma_addr_t dma_addr, u32 *result) { struct nvme_command c; @@ -849,7 +849,7 @@ static int nvme_get_features(struct nvme_dev *dev, unsigned fid, c.features.prp1 = cpu_to_le64(dma_addr); c.features.fid = cpu_to_le32(fid); - return nvme_submit_admin_cmd(dev, &c, NULL); + return nvme_submit_admin_cmd(dev, &c, result); } static int nvme_set_features(struct nvme_dev *dev, unsigned fid, @@ -1535,7 +1535,7 @@ static int __devinit nvme_dev_add(struct nvme_dev *dev) continue; res = nvme_get_features(dev, NVME_FEAT_LBA_RANGE, i, - dma_addr + 4096); + dma_addr + 4096, NULL); if (res) continue; -- cgit v1.2.3 From 6ecec74520d8a357726e6c12f99080dbe7b347dd Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Wed, 26 Sep 2012 12:49:27 -0600 Subject: NVMe: Define SMART log This data structure is defined in the NVMe specification. It's not used by the kernel, but is available for use by userspace software. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox --- drivers/block/nvme.c | 1 + include/linux/nvme.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index c1d5444f0cb3..270805cf8d42 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -135,6 +135,7 @@ static inline void _nvme_check_size(void) BUILD_BUG_ON(sizeof(struct nvme_id_ctrl) != 4096); BUILD_BUG_ON(sizeof(struct nvme_id_ns) != 4096); BUILD_BUG_ON(sizeof(struct nvme_lba_range_type) != 64); + BUILD_BUG_ON(sizeof(struct nvme_smart_log) != 512); } typedef void (*nvme_completion_fn)(struct nvme_dev *, void *, diff --git a/include/linux/nvme.h b/include/linux/nvme.h index c25cccaa555a..4fa3b0b9b071 100644 --- a/include/linux/nvme.h +++ b/include/linux/nvme.h @@ -137,6 +137,34 @@ enum { NVME_LBAF_RP_DEGRADED = 3, }; +struct nvme_smart_log { + __u8 critical_warning; + __u8 temperature[2]; + __u8 avail_spare; + __u8 spare_thresh; + __u8 percent_used; + __u8 rsvd6[26]; + __u8 data_units_read[16]; + __u8 data_units_written[16]; + __u8 host_reads[16]; + __u8 host_writes[16]; + __u8 ctrl_busy_time[16]; + __u8 power_cycles[16]; + __u8 power_on_hours[16]; + __u8 unsafe_shutdowns[16]; + __u8 media_errors[16]; + __u8 num_err_log_entries[16]; + __u8 rsvd192[320]; +}; + +enum { + NVME_SMART_CRIT_SPARE = 1 << 0, + NVME_SMART_CRIT_TEMPERATURE = 1 << 1, + NVME_SMART_CRIT_RELIABILITY = 1 << 2, + NVME_SMART_CRIT_MEDIA = 1 << 3, + NVME_SMART_CRIT_VOLATILE_MEMORY = 1 << 4, +}; + struct nvme_lba_range_type { __u8 type; __u8 attributes; -- cgit v1.2.3 From 2b1960341576bf51c01b12fefeb1cc53820923e7 Mon Sep 17 00:00:00 2001 From: Keith Busch Date: Tue, 6 Nov 2012 11:59:23 -0700 Subject: NVMe: Initialize iod nents to 0 For commands that do not map a scatter list, we need to initilaize the iod's number of sg entries (nents) to 0 and not unmap in this case. Signed-off-by: Keith Busch Signed-off-by: Matthew Wilcox --- drivers/block/nvme.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c index 270805cf8d42..993c014d195a 100644 --- a/drivers/block/nvme.c +++ b/drivers/block/nvme.c @@ -337,6 +337,7 @@ nvme_alloc_iod(unsigned nseg, unsigned nbytes, gfp_t gfp) iod->offset = offsetof(struct nvme_iod, sg[nseg]); iod->npages = -1; iod->length = nbytes; + iod->nents = 0; } return iod; @@ -377,7 +378,8 @@ static void bio_completion(struct nvme_dev *dev, void *ctx, struct bio *bio = iod->private; u16 status = le16_to_cpup(&cqe->status) >> 1; - dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, + if (iod->nents) + dma_unmap_sg(&dev->pci_dev->dev, iod->sg, iod->nents, bio_data_dir(bio) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); nvme_free_iod(dev, iod); if (status) { -- cgit v1.2.3 From 3f63c340a72f2872a9362245cb2e03f3d2bb73a6 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Tue, 19 Feb 2013 11:54:16 -0500 Subject: Bluetooth: Add support for atheros 04ca:3004 device to ath3k Yet another version of the atheros bluetooth chipset T: Bus=01 Lev=02 Prnt=02 Port=03 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=04ca ProdID=3004 Rev=00.01 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C: #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I: If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb I: If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb This resolves https://bugzilla.redhat.com/show_bug.cgi?id=844750 Reported-by: niktr@mail.ru Signed-off-by: Josh Boyer Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 33c9a44a9678..b9908dd84529 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -76,6 +76,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0CF3, 0x3004) }, { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, + { USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3005) }, { USB_DEVICE(0x04CA, 0x3006) }, { USB_DEVICE(0x04CA, 0x3008) }, @@ -108,6 +109,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 7e351e345476..59cde8e882ff 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -134,6 +134,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, -- cgit v1.2.3 From bbfa57c0f2243a7c31fd248d22e9861a2802cad5 Mon Sep 17 00:00:00 2001 From: Sebastian Riemer Date: Thu, 21 Feb 2013 13:28:09 +1100 Subject: md: protect against crash upon fsync on ro array If an fsync occurs on a read-only array, we need to send a completion for the IO and may not increment the active IO count. Otherwise, we hit a bug trace and can't stop the MD array anymore. By advice of Christoph Hellwig we return success upon a flush request but we return -EROFS for other writes. We detect flush requests by checking if the bio has zero sectors. This patch is suitable to any -stable kernel to which it applies. Cc: Christoph Hellwig Cc: Ben Hutchings Cc: NeilBrown Cc: stable@vger.kernel.org Signed-off-by: Sebastian Riemer Reported-by: Ben Hutchings Acked-by: Paul Menzel Signed-off-by: NeilBrown --- drivers/md/md.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 3db3d1b271f7..1e634a68541e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -307,6 +307,10 @@ static void md_make_request(struct request_queue *q, struct bio *bio) bio_io_error(bio); return; } + if (mddev->ro == 1 && unlikely(rw == WRITE)) { + bio_endio(bio, bio_sectors(bio) == 0 ? 0 : -EROFS); + return; + } smp_rmb(); /* Ensure implications of 'active' are visible */ rcu_read_lock(); if (mddev->suspended) { -- cgit v1.2.3 From 81bb5d31fbf3893a8e041c649dea704dd11d5272 Mon Sep 17 00:00:00 2001 From: Kamal Mostafa Date: Thu, 21 Feb 2013 11:55:05 -0800 Subject: Input: cypress_ps2 - fix trackpadi found in Dell XPS12 Avoid firmware glitch in Cypress PS/2 Trackpad firmware version 11 (as observed in Dell XPS12) which prevents driver from recognizing the trackpad. BugLink: http://launchpad.net/bugs/1103594 Signed-off-by: Kamal Mostafa Cc: Dudley Du Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/cypress_ps2.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/cypress_ps2.c b/drivers/input/mouse/cypress_ps2.c index 1673dc6c8092..f51765fff054 100644 --- a/drivers/input/mouse/cypress_ps2.c +++ b/drivers/input/mouse/cypress_ps2.c @@ -236,6 +236,13 @@ static int cypress_read_fw_version(struct psmouse *psmouse) cytp->fw_version = param[2] & FW_VERSION_MASX; cytp->tp_metrics_supported = (param[2] & TP_METRICS_MASK) ? 1 : 0; + /* + * Trackpad fw_version 11 (in Dell XPS12) yields a bogus response to + * CYTP_CMD_READ_TP_METRICS so do not try to use it. LP: #1103594. + */ + if (cytp->fw_version >= 11) + cytp->tp_metrics_supported = 0; + psmouse_dbg(psmouse, "cytp->fw_version = %d\n", cytp->fw_version); psmouse_dbg(psmouse, "cytp->tp_metrics_supported = %d\n", cytp->tp_metrics_supported); @@ -258,6 +265,9 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse) cytp->tp_res_x = cytp->tp_max_abs_x / cytp->tp_width; cytp->tp_res_y = cytp->tp_max_abs_y / cytp->tp_high; + if (!cytp->tp_metrics_supported) + return 0; + memset(param, 0, sizeof(param)); if (cypress_send_ext_cmd(psmouse, CYTP_CMD_READ_TP_METRICS, param) == 0) { /* Update trackpad parameters. */ @@ -315,18 +325,15 @@ static int cypress_read_tp_metrics(struct psmouse *psmouse) static int cypress_query_hardware(struct psmouse *psmouse) { - struct cytp_data *cytp = psmouse->private; int ret; ret = cypress_read_fw_version(psmouse); if (ret) return ret; - if (cytp->tp_metrics_supported) { - ret = cypress_read_tp_metrics(psmouse); - if (ret) - return ret; - } + ret = cypress_read_tp_metrics(psmouse); + if (ret) + return ret; return 0; } -- cgit v1.2.3 From d18e53fce2f6e42bfb8ac157547dd3f804385749 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Thu, 21 Feb 2013 22:58:20 -0800 Subject: Input: ALPS - remove unused argument to alps_enter_command_mode() Now that alps_identify() explicitly issues an EC report using alps_rpt_cmd(), we no longer need to look at the magic numbers returned by alps_enter_command_mode(). Signed-off-by: Kevin Cernekee Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 7b99fc7c9438..9c97531bd2cd 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -994,8 +994,7 @@ static int alps_rpt_cmd(struct psmouse *psmouse, int init_command, return 0; } -static int alps_enter_command_mode(struct psmouse *psmouse, - unsigned char *resp) +static int alps_enter_command_mode(struct psmouse *psmouse) { unsigned char param[4]; @@ -1009,9 +1008,6 @@ static int alps_enter_command_mode(struct psmouse *psmouse, "unknown response while entering command mode\n"); return -1; } - - if (resp) - *resp = param[2]; return 0; } @@ -1176,7 +1172,7 @@ static int alps_passthrough_mode_v3(struct psmouse *psmouse, { int reg_val, ret = -1; - if (alps_enter_command_mode(psmouse, NULL)) + if (alps_enter_command_mode(psmouse)) return -1; reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x0008); @@ -1216,7 +1212,7 @@ static int alps_probe_trackstick_v3(struct psmouse *psmouse, int reg_base) { int ret = -EIO, reg_val; - if (alps_enter_command_mode(psmouse, NULL)) + if (alps_enter_command_mode(psmouse)) goto error; reg_val = alps_command_mode_read_reg(psmouse, reg_base + 0x08); @@ -1279,7 +1275,7 @@ static int alps_setup_trackstick_v3(struct psmouse *psmouse, int reg_base) * supported by this driver. If bit 1 isn't set the packet * format is different. */ - if (alps_enter_command_mode(psmouse, NULL) || + if (alps_enter_command_mode(psmouse) || alps_command_mode_write_reg(psmouse, reg_base + 0x08, 0x82) || alps_exit_command_mode(psmouse)) @@ -1306,7 +1302,7 @@ static int alps_hw_init_v3(struct psmouse *psmouse) alps_setup_trackstick_v3(psmouse, ALPS_REG_BASE_PINNACLE) == -EIO) goto error; - if (alps_enter_command_mode(psmouse, NULL) || + if (alps_enter_command_mode(psmouse) || alps_absolute_mode_v3(psmouse)) { psmouse_err(psmouse, "Failed to enter absolute mode\n"); goto error; @@ -1381,7 +1377,7 @@ static int alps_hw_init_rushmore_v3(struct psmouse *psmouse) priv->flags &= ~ALPS_DUALPOINT; } - if (alps_enter_command_mode(psmouse, NULL) || + if (alps_enter_command_mode(psmouse) || alps_command_mode_read_reg(psmouse, 0xc2d9) == -1 || alps_command_mode_write_reg(psmouse, 0xc2cb, 0x00)) goto error; @@ -1431,7 +1427,7 @@ static int alps_hw_init_v4(struct psmouse *psmouse) struct ps2dev *ps2dev = &psmouse->ps2dev; unsigned char param[4]; - if (alps_enter_command_mode(psmouse, NULL)) + if (alps_enter_command_mode(psmouse)) goto error; if (alps_absolute_mode_v4(psmouse)) { -- cgit v1.2.3 From 75af9e56c1e309a4132d15120d7061656609b84e Mon Sep 17 00:00:00 2001 From: Dave Turvene Date: Thu, 21 Feb 2013 22:58:28 -0800 Subject: Input: ALPS - add "Dolphin V1" touchpad support These touchpads use a different protocol; they have been seen on Dell N5110, Dell 17R SE, and others. The official ALPS driver identifies them by looking for an exact match on the E7 report: 73 03 50. Dolphin V1 returns an EC report of 73 01 xx (02 and 0d have been seen); Dolphin V2 returns an EC report of 73 02 xx (02 has been seen). Dolphin V2 probably needs a different initialization sequence and/or report parser, so it is left for a future commit. Signed-off-by: Dave Turvene Signed-off-by: Kevin Cernekee Signed-off-by: Dmitry Torokhov --- drivers/input/mouse/alps.c | 67 ++++++++++++++++++++++++++++++++++++++++++++-- drivers/input/mouse/alps.h | 1 + 2 files changed, 66 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 9c97531bd2cd..0238e0e14335 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c @@ -490,6 +490,29 @@ static void alps_decode_rushmore(struct alps_fields *f, unsigned char *p) f->y_map |= (p[5] & 0x20) << 6; } +static void alps_decode_dolphin(struct alps_fields *f, unsigned char *p) +{ + f->first_mp = !!(p[0] & 0x02); + f->is_mp = !!(p[0] & 0x20); + + f->fingers = ((p[0] & 0x6) >> 1 | + (p[0] & 0x10) >> 2); + f->x_map = ((p[2] & 0x60) >> 5) | + ((p[4] & 0x7f) << 2) | + ((p[5] & 0x7f) << 9) | + ((p[3] & 0x07) << 16) | + ((p[3] & 0x70) << 15) | + ((p[0] & 0x01) << 22); + f->y_map = (p[1] & 0x7f) | + ((p[2] & 0x1f) << 7); + + f->x = ((p[1] & 0x7f) | ((p[4] & 0x0f) << 7)); + f->y = ((p[2] & 0x7f) | ((p[4] & 0xf0) << 3)); + f->z = (p[0] & 4) ? 0 : p[5] & 0x7f; + + alps_decode_buttons_v3(f, p); +} + static void alps_process_touchpad_packet_v3(struct psmouse *psmouse) { struct alps_data *priv = psmouse->private; @@ -874,7 +897,8 @@ static psmouse_ret_t alps_process_byte(struct psmouse *psmouse) } /* Bytes 2 - pktsize should have 0 in the highest bit */ - if (psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && + if (priv->proto_version != ALPS_PROTO_V5 && + psmouse->pktcnt >= 2 && psmouse->pktcnt <= psmouse->pktsize && (psmouse->packet[psmouse->pktcnt - 1] & 0x80)) { psmouse_dbg(psmouse, "refusing packet[%i] = %x\n", psmouse->pktcnt - 1, @@ -1003,7 +1027,8 @@ static int alps_enter_command_mode(struct psmouse *psmouse) return -1; } - if (param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) { + if ((param[0] != 0x88 || (param[1] != 0x07 && param[1] != 0x08)) && + param[0] != 0x73) { psmouse_dbg(psmouse, "unknown response while entering command mode\n"); return -1; @@ -1495,6 +1520,23 @@ error: return -1; } +static int alps_hw_init_dolphin_v1(struct psmouse *psmouse) +{ + struct ps2dev *ps2dev = &psmouse->ps2dev; + unsigned char param[2]; + + /* This is dolphin "v1" as empirically defined by florin9doi */ + param[0] = 0x64; + param[1] = 0x28; + + if (ps2_command(ps2dev, NULL, PSMOUSE_CMD_SETSTREAM) || + ps2_command(ps2dev, ¶m[0], PSMOUSE_CMD_SETRATE) || + ps2_command(ps2dev, ¶m[1], PSMOUSE_CMD_SETRATE)) + return -1; + + return 0; +} + static void alps_set_defaults(struct alps_data *priv) { priv->byte0 = 0x8f; @@ -1528,6 +1570,21 @@ static void alps_set_defaults(struct alps_data *priv) priv->nibble_commands = alps_v4_nibble_commands; priv->addr_command = PSMOUSE_CMD_DISABLE; break; + case ALPS_PROTO_V5: + priv->hw_init = alps_hw_init_dolphin_v1; + priv->process_packet = alps_process_packet_v3; + priv->decode_fields = alps_decode_dolphin; + priv->set_abs_params = alps_set_abs_params_mt; + priv->nibble_commands = alps_v3_nibble_commands; + priv->addr_command = PSMOUSE_CMD_RESET_WRAP; + priv->byte0 = 0xc8; + priv->mask0 = 0xc8; + priv->flags = 0; + priv->x_max = 1360; + priv->y_max = 660; + priv->x_bits = 23; + priv->y_bits = 12; + break; } } @@ -1587,6 +1644,12 @@ static int alps_identify(struct psmouse *psmouse, struct alps_data *priv) return -EIO; if (alps_match_table(psmouse, priv, e7, ec) == 0) { + return 0; + } else if (e7[0] == 0x73 && e7[1] == 0x03 && e7[2] == 0x50 && + ec[0] == 0x73 && ec[1] == 0x01) { + priv->proto_version = ALPS_PROTO_V5; + alps_set_defaults(priv); + return 0; } else if (ec[0] == 0x88 && ec[1] == 0x08) { priv->proto_version = ALPS_PROTO_V3; diff --git a/drivers/input/mouse/alps.h b/drivers/input/mouse/alps.h index 970480551b6e..eee59853b9ce 100644 --- a/drivers/input/mouse/alps.h +++ b/drivers/input/mouse/alps.h @@ -16,6 +16,7 @@ #define ALPS_PROTO_V2 2 #define ALPS_PROTO_V3 3 #define ALPS_PROTO_V4 4 +#define ALPS_PROTO_V5 5 /** * struct alps_model_info - touchpad ID table -- cgit v1.2.3 From c8dc9c654794a765ca61baed07f84ed8aaa7ca8c Mon Sep 17 00:00:00 2001 From: Joe Lawrence Date: Thu, 21 Feb 2013 13:28:09 +1100 Subject: md: raid1,10: Handle REQ_WRITE_SAME flag in write bios Set mddev queue's max_write_same_sectors to its chunk_sector value (before disk_stack_limits merges the underlying disk limits.) With that in place, be sure to handle writes coming down from the block layer that have the REQ_WRITE_SAME flag set. That flag needs to be copied into any newly cloned write bio. Signed-off-by: Joe Lawrence Acked-by: "Martin K. Petersen" Signed-off-by: NeilBrown --- drivers/md/raid1.c | 7 ++++++- drivers/md/raid10.c | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index d5bddfc4010e..6e5d5a5f9cb4 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1000,6 +1000,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); const unsigned long do_discard = (bio->bi_rw & (REQ_DISCARD | REQ_SECURE)); + const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME); struct md_rdev *blocked_rdev; struct blk_plug_cb *cb; struct raid1_plug_cb *plug = NULL; @@ -1301,7 +1302,8 @@ read_again: conf->mirrors[i].rdev->data_offset); mbio->bi_bdev = conf->mirrors[i].rdev->bdev; mbio->bi_end_io = raid1_end_write_request; - mbio->bi_rw = WRITE | do_flush_fua | do_sync | do_discard; + mbio->bi_rw = + WRITE | do_flush_fua | do_sync | do_discard | do_same; mbio->bi_private = r1_bio; atomic_inc(&r1_bio->remaining); @@ -2818,6 +2820,9 @@ static int run(struct mddev *mddev) if (IS_ERR(conf)) return PTR_ERR(conf); + if (mddev->queue) + blk_queue_max_write_same_sectors(mddev->queue, + mddev->chunk_sectors); rdev_for_each(rdev, mddev) { if (!mddev->gendisk) continue; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 64d48249c03b..1a74c12f0a6e 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1105,6 +1105,7 @@ static void make_request(struct mddev *mddev, struct bio * bio) const unsigned long do_fua = (bio->bi_rw & REQ_FUA); const unsigned long do_discard = (bio->bi_rw & (REQ_DISCARD | REQ_SECURE)); + const unsigned long do_same = (bio->bi_rw & REQ_WRITE_SAME); unsigned long flags; struct md_rdev *blocked_rdev; struct blk_plug_cb *cb; @@ -1460,7 +1461,8 @@ retry_write: rdev)); mbio->bi_bdev = rdev->bdev; mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; + mbio->bi_rw = + WRITE | do_sync | do_fua | do_discard | do_same; mbio->bi_private = r10_bio; atomic_inc(&r10_bio->remaining); @@ -1502,7 +1504,8 @@ retry_write: r10_bio, rdev)); mbio->bi_bdev = rdev->bdev; mbio->bi_end_io = raid10_end_write_request; - mbio->bi_rw = WRITE | do_sync | do_fua | do_discard; + mbio->bi_rw = + WRITE | do_sync | do_fua | do_discard | do_same; mbio->bi_private = r10_bio; atomic_inc(&r10_bio->remaining); @@ -3569,6 +3572,8 @@ static int run(struct mddev *mddev) if (mddev->queue) { blk_queue_max_discard_sectors(mddev->queue, mddev->chunk_sectors); + blk_queue_max_write_same_sectors(mddev->queue, + mddev->chunk_sectors); blk_queue_io_min(mddev->queue, chunk_size); if (conf->geo.raid_disks % conf->geo.near_copies) blk_queue_io_opt(mddev->queue, chunk_size * conf->geo.raid_disks); -- cgit v1.2.3 From 4c0ca26bd260dddf3b9781758cb5e2df3f74d4a3 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 21 Feb 2013 13:28:09 +1100 Subject: MD RAID10: Minor non-functional code changes Changes include assigning 'addr' from 's' instead of 'sector' to be consistent with the way the code does it just a few lines later and using '%=' vs a conditional and subtraction. Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- drivers/md/raid10.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 1a74c12f0a6e..de174ad6f8bd 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -552,14 +552,13 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio) for (n = 0; n < geo->near_copies; n++) { int d = dev; sector_t s = sector; - r10bio->devs[slot].addr = sector; r10bio->devs[slot].devnum = d; + r10bio->devs[slot].addr = s; slot++; for (f = 1; f < geo->far_copies; f++) { d += geo->near_copies; - if (d >= geo->raid_disks) - d -= geo->raid_disks; + d %= geo->raid_disks; s += geo->stride; r10bio->devs[slot].devnum = d; r10bio->devs[slot].addr = s; -- cgit v1.2.3 From 475901aff15841fb0a81e7546517407779a9b061 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 21 Feb 2013 13:28:10 +1100 Subject: MD RAID10: Improve redundancy for 'far' and 'offset' algorithms (part 1) The MD RAID10 'far' and 'offset' algorithms make copies of entire stripe widths - copying them to a different location on the same devices after shifting the stripe. An example layout of each follows below: "far" algorithm dev1 dev2 dev3 dev4 dev5 dev6 ==== ==== ==== ==== ==== ==== A B C D E F G H I J K L ... F A B C D E --> Copy of stripe0, but shifted by 1 L G H I J K ... "offset" algorithm dev1 dev2 dev3 dev4 dev5 dev6 ==== ==== ==== ==== ==== ==== A B C D E F F A B C D E --> Copy of stripe0, but shifted by 1 G H I J K L L G H I J K ... Redundancy for these algorithms is gained by shifting the copied stripes one device to the right. This patch proposes that array be divided into sets of adjacent devices and when the stripe copies are shifted, they wrap on set boundaries rather than the array size boundary. That is, for the purposes of shifting, the copies are confined to their sets within the array. The sets are 'near_copies * far_copies' in size. The above "far" algorithm example would change to: "far" algorithm dev1 dev2 dev3 dev4 dev5 dev6 ==== ==== ==== ==== ==== ==== A B C D E F G H I J K L ... B A D C F E --> Copy of stripe0, shifted 1, 2-dev sets H G J I L K Dev sets are 1-2, 3-4, 5-6 ... This has the affect of improving the redundancy of the array. We can always sustain at least one failure, but sometimes more than one can be handled. In the first examples, the pairs of devices that CANNOT fail together are: (1,2) (2,3) (3,4) (4,5) (5,6) (1, 6) [40% of possible pairs] In the example where the copies are confined to sets, the pairs of devices that cannot fail together are: (1,2) (3,4) (5,6) [20% of possible pairs] We cannot simply replace the old algorithms, so the 17th bit of the 'layout' variable is used to indicate whether we use the old or new method of computing the shift. (This is similar to the way the 16th bit indicates whether the "far" algorithm or the "offset" algorithm is being used.) This patch only handles the cases where the number of total raid disks is a multiple of 'far_copies'. A follow-on patch addresses the condition where this is not true. Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- drivers/md/raid10.c | 58 ++++++++++++++++++++++++++++++++++++----------------- drivers/md/raid10.h | 5 +++++ 2 files changed, 45 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index de174ad6f8bd..70b58b4bcf89 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -38,21 +38,36 @@ * near_copies (stored in low byte of layout) * far_copies (stored in second byte of layout) * far_offset (stored in bit 16 of layout ) + * use_far_sets (stored in bit 17 of layout ) * - * The data to be stored is divided into chunks using chunksize. - * Each device is divided into far_copies sections. - * In each section, chunks are laid out in a style similar to raid0, but - * near_copies copies of each chunk is stored (each on a different drive). - * The starting device for each section is offset near_copies from the starting - * device of the previous section. - * Thus they are (near_copies*far_copies) of each chunk, and each is on a different - * drive. - * near_copies and far_copies must be at least one, and their product is at most - * raid_disks. + * The data to be stored is divided into chunks using chunksize. Each device + * is divided into far_copies sections. In each section, chunks are laid out + * in a style similar to raid0, but near_copies copies of each chunk is stored + * (each on a different drive). The starting device for each section is offset + * near_copies from the starting device of the previous section. Thus there + * are (near_copies * far_copies) of each chunk, and each is on a different + * drive. near_copies and far_copies must be at least one, and their product + * is at most raid_disks. * * If far_offset is true, then the far_copies are handled a bit differently. - * The copies are still in different stripes, but instead of be very far apart - * on disk, there are adjacent stripes. + * The copies are still in different stripes, but instead of being very far + * apart on disk, there are adjacent stripes. + * + * The far and offset algorithms are handled slightly differently if + * 'use_far_sets' is true. In this case, the array's devices are grouped into + * sets that are (near_copies * far_copies) in size. The far copied stripes + * are still shifted by 'near_copies' devices, but this shifting stays confined + * to the set rather than the entire array. This is done to improve the number + * of device combinations that can fail without causing the array to fail. + * Example 'far' algorithm w/o 'use_far_sets' (each letter represents a chunk + * on a device): + * A B C D A B C D E + * ... ... + * D A B C E A B C D + * Example 'far' algorithm w/ 'use_far_sets' enabled (sets illustrated w/ []'s): + * [A B] [C D] [A B] [C D E] + * |...| |...| |...| | ... | + * [B A] [D C] [B A] [E C D] */ /* @@ -551,14 +566,18 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio) /* and calculate all the others */ for (n = 0; n < geo->near_copies; n++) { int d = dev; + int set; sector_t s = sector; r10bio->devs[slot].devnum = d; r10bio->devs[slot].addr = s; slot++; for (f = 1; f < geo->far_copies; f++) { + set = d / geo->far_set_size; d += geo->near_copies; - d %= geo->raid_disks; + d %= geo->far_set_size; + d += geo->far_set_size * set; + s += geo->stride; r10bio->devs[slot].devnum = d; r10bio->devs[slot].addr = s; @@ -594,6 +613,8 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev) * or recovery, so reshape isn't happening */ struct geom *geo = &conf->geo; + int far_set_start = (dev / geo->far_set_size) * geo->far_set_size; + int far_set_size = geo->far_set_size; offset = sector & geo->chunk_mask; if (geo->far_offset) { @@ -601,13 +622,13 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev) chunk = sector >> geo->chunk_shift; fc = sector_div(chunk, geo->far_copies); dev -= fc * geo->near_copies; - if (dev < 0) - dev += geo->raid_disks; + if (dev < far_set_start) + dev += far_set_size; } else { while (sector >= geo->stride) { sector -= geo->stride; - if (dev < geo->near_copies) - dev += geo->raid_disks - geo->near_copies; + if (dev < (geo->near_copies + far_set_start)) + dev += far_set_size - geo->near_copies; else dev -= geo->near_copies; } @@ -3438,7 +3459,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) disks = mddev->raid_disks + mddev->delta_disks; break; } - if (layout >> 17) + if (layout >> 18) return -1; if (chunk < (PAGE_SIZE >> 9) || !is_power_of_2(chunk)) @@ -3450,6 +3471,7 @@ static int setup_geo(struct geom *geo, struct mddev *mddev, enum geo_type new) geo->near_copies = nc; geo->far_copies = fc; geo->far_offset = fo; + geo->far_set_size = (layout & (1<<17)) ? disks / fc : disks; geo->chunk_mask = chunk - 1; geo->chunk_shift = ffz(~chunk); return nc*fc; diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 1054cf602345..157d69e83ff4 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h @@ -33,6 +33,11 @@ struct r10conf { * far_offset, in which case it is * 1 stripe. */ + int far_set_size; /* The number of devices in a set, + * where a 'set' are devices that + * contain far/offset copies of + * each other. + */ int chunk_shift; /* shift from chunks to sectors */ sector_t chunk_mask; } prev, geo; -- cgit v1.2.3 From 9a3152ab024867100f2f50d124b998d05fb1c3f6 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 21 Feb 2013 13:28:10 +1100 Subject: MD RAID10: Improve redundancy for 'far' and 'offset' algorithms (part 2) MD RAID10: Improve redundancy for 'far' and 'offset' algorithms (part 2) This patch addresses raid arrays that have a number of devices that cannot be evenly divided by 'far_copies'. (E.g. 5 devices, far_copies = 2) This case must be handled differently because it causes that last set to be of a different size than the rest of the sets. We must compute a new modulo for this last set so that copied chunks are properly wrapped around. Example use_far_sets=1, far_copies=2, near_copies=1, devices=5: "far" algorithm dev1 dev2 dev3 dev4 dev5 ==== ==== ==== ==== ==== [ A B ] [ C D E ] [ G H ] [ I J K ] ... [ B A ] [ E C D ] --> nominal set of 2 and last set of 3 [ H G ] [ K I J ] []'s show far/offset sets Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- drivers/md/raid10.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 70b58b4bcf89..61ed150bd0cf 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -550,6 +550,13 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio) sector_t stripe; int dev; int slot = 0; + int last_far_set_start, last_far_set_size; + + last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1; + last_far_set_start *= geo->far_set_size; + + last_far_set_size = geo->far_set_size; + last_far_set_size += (geo->raid_disks % geo->far_set_size); /* now calculate first sector/dev */ chunk = r10bio->sector >> geo->chunk_shift; @@ -575,9 +582,16 @@ static void __raid10_find_phys(struct geom *geo, struct r10bio *r10bio) for (f = 1; f < geo->far_copies; f++) { set = d / geo->far_set_size; d += geo->near_copies; - d %= geo->far_set_size; - d += geo->far_set_size * set; + if ((geo->raid_disks % geo->far_set_size) && + (d > last_far_set_start)) { + d -= last_far_set_start; + d %= last_far_set_size; + d += last_far_set_start; + } else { + d %= geo->far_set_size; + d += geo->far_set_size * set; + } s += geo->stride; r10bio->devs[slot].devnum = d; r10bio->devs[slot].addr = s; @@ -615,6 +629,18 @@ static sector_t raid10_find_virt(struct r10conf *conf, sector_t sector, int dev) struct geom *geo = &conf->geo; int far_set_start = (dev / geo->far_set_size) * geo->far_set_size; int far_set_size = geo->far_set_size; + int last_far_set_start; + + if (geo->raid_disks % geo->far_set_size) { + last_far_set_start = (geo->raid_disks / geo->far_set_size) - 1; + last_far_set_start *= geo->far_set_size; + + if (dev >= last_far_set_start) { + far_set_size = geo->far_set_size; + far_set_size += (geo->raid_disks % geo->far_set_size); + far_set_start = last_far_set_start; + } + } offset = sector & geo->chunk_mask; if (geo->far_offset) { -- cgit v1.2.3 From fe5d2f4a15967bbe907e7b3e31e49dae7af7cc6b Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 21 Feb 2013 13:28:10 +1100 Subject: DM RAID: Add support for MD's RAID10 "far" and "offset" algorithms DM RAID: Add support for MD's RAID10 "far" and "offset" algorithms Until now, dm-raid.c only supported the "near" algorthm of MD's RAID10 implementation. This patch adds support for the "far" and "offset" algorithms, but only with the improved redundancy that is brought with the introduction of the 'use_far_sets' bit, which shifts copied stripes according to smaller sets vs the entire array. That is, the 17th bit of the 'layout' variable that defines the RAID10 implementation will always be set. (More information on how the 'layout' variable selects the RAID10 algorithm can be found in the opening comments of drivers/md/raid10.c.) Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- Documentation/device-mapper/dm-raid.txt | 44 ++++++++++-- drivers/md/dm-raid.c | 123 ++++++++++++++++++++++++++------ 2 files changed, 140 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt index 56fb62b09fc5..b428556197c9 100644 --- a/Documentation/device-mapper/dm-raid.txt +++ b/Documentation/device-mapper/dm-raid.txt @@ -30,6 +30,7 @@ The target is named "raid" and it accepts the following parameters: raid10 Various RAID10 inspired algorithms chosen by additional params - RAID10: Striped Mirrors (aka 'Striping on top of mirrors') - RAID1E: Integrated Adjacent Stripe Mirroring + - RAID1E: Integrated Offset Stripe Mirroring - and other similar RAID10 variants Reference: Chapter 4 of @@ -64,15 +65,15 @@ The target is named "raid" and it accepts the following parameters: synchronisation state for each region. [raid10_copies <# copies>] - [raid10_format near] + [raid10_format ] These two options are used to alter the default layout of a RAID10 configuration. The number of copies is can be - specified, but the default is 2. There are other variations - to how the copies are laid down - the default and only current - option is "near". Near copies are what most people think of - with respect to mirroring. If these options are left - unspecified, or 'raid10_copies 2' and/or 'raid10_format near' - are given, then the layouts for 2, 3 and 4 devices are: + specified, but the default is 2. There are also three + variations to how the copies are laid down - the default + is "near". Near copies are what most people think of with + respect to mirroring. If these options are left unspecified, + or 'raid10_copies 2' and/or 'raid10_format near' are given, + then the layouts for 2, 3 and 4 devices are: 2 drives 3 drives 4 drives -------- ---------- -------------- A1 A1 A1 A1 A2 A1 A1 A2 A2 @@ -85,6 +86,33 @@ The target is named "raid" and it accepts the following parameters: 3-device layout is what might be called a 'RAID1E - Integrated Adjacent Stripe Mirroring'. + If 'raid10_copies 2' and 'raid10_format far', then the layouts + for 2, 3 and 4 devices are: + 2 drives 3 drives 4 drives + -------- -------------- -------------------- + A1 A2 A1 A2 A3 A1 A2 A3 A4 + A3 A4 A4 A5 A6 A5 A6 A7 A8 + A5 A6 A7 A8 A9 A9 A10 A11 A12 + .. .. .. .. .. .. .. .. .. + A2 A1 A3 A1 A2 A2 A1 A4 A3 + A4 A3 A6 A4 A5 A6 A5 A8 A7 + A6 A5 A9 A7 A8 A10 A9 A12 A11 + .. .. .. .. .. .. .. .. .. + + If 'raid10_copies 2' and 'raid10_format offset', then the + layouts for 2, 3 and 4 devices are: + 2 drives 3 drives 4 drives + -------- ------------ ----------------- + A1 A2 A1 A2 A3 A1 A2 A3 A4 + A2 A1 A3 A1 A2 A2 A1 A4 A3 + A3 A4 A4 A5 A6 A5 A6 A7 A8 + A4 A3 A6 A4 A5 A6 A5 A8 A7 + A5 A6 A7 A8 A9 A9 A10 A11 A12 + A6 A5 A9 A7 A8 A10 A9 A12 A11 + .. .. .. .. .. .. .. .. .. + Here we see layouts closely akin to 'RAID1E - Integrated + Offset Stripe Mirroring'. + <#raid_devs>: The number of devices composing the array. Each device consists of two entries. The first is the device containing the metadata (if any); the second is the one containing the @@ -142,3 +170,5 @@ Version History 1.3.0 Added support for RAID 10 1.3.1 Allow device replacement/rebuild for RAID 10 1.3.2 Fix/improve redundancy checking for RAID10 +1.4.0 Non-functional change. Removes arg from mapping function. +1.4.1 Add RAID10 "far" and "offset" algorithm support. diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c index 9e58dbd8d8cb..22fd55993723 100644 --- a/drivers/md/dm-raid.c +++ b/drivers/md/dm-raid.c @@ -91,15 +91,44 @@ static struct raid_type { {"raid6_nc", "RAID6 (N continue)", 2, 4, 6, ALGORITHM_ROTATING_N_CONTINUE} }; +static char *raid10_md_layout_to_format(int layout) +{ + /* + * Bit 16 and 17 stand for "offset" and "use_far_sets" + * Refer to MD's raid10.c for details + */ + if ((layout & 0x10000) && (layout & 0x20000)) + return "offset"; + + if ((layout & 0xFF) > 1) + return "near"; + + return "far"; +} + static unsigned raid10_md_layout_to_copies(int layout) { - return layout & 0xFF; + if ((layout & 0xFF) > 1) + return layout & 0xFF; + return (layout >> 8) & 0xFF; } static int raid10_format_to_md_layout(char *format, unsigned copies) { - /* 1 "far" copy, and 'copies' "near" copies */ - return (1 << 8) | (copies & 0xFF); + unsigned n = 1, f = 1; + + if (!strcmp("near", format)) + n = copies; + else + f = copies; + + if (!strcmp("offset", format)) + return 0x30000 | (f << 8) | n; + + if (!strcmp("far", format)) + return 0x20000 | (f << 8) | n; + + return (f << 8) | n; } static struct raid_type *get_raid_type(char *name) @@ -352,6 +381,7 @@ static int validate_raid_redundancy(struct raid_set *rs) { unsigned i, rebuild_cnt = 0; unsigned rebuilds_per_group, copies, d; + unsigned group_size, last_group_start; for (i = 0; i < rs->md.raid_disks; i++) if (!test_bit(In_sync, &rs->dev[i].rdev.flags) || @@ -379,9 +409,6 @@ static int validate_raid_redundancy(struct raid_set *rs) * as long as the failed devices occur in different mirror * groups (i.e. different stripes). * - * Right now, we only allow for "near" copies. When other - * formats are added, we will have to check those too. - * * When checking "near" format, make sure no adjacent devices * have failed beyond what can be handled. In addition to the * simple case where the number of devices is a multiple of the @@ -391,14 +418,41 @@ static int validate_raid_redundancy(struct raid_set *rs) * A A B B C * C D D E E */ - for (i = 0; i < rs->md.raid_disks * copies; i++) { - if (!(i % copies)) + if (!strcmp("near", raid10_md_layout_to_format(rs->md.layout))) { + for (i = 0; i < rs->md.raid_disks * copies; i++) { + if (!(i % copies)) + rebuilds_per_group = 0; + d = i % rs->md.raid_disks; + if ((!rs->dev[d].rdev.sb_page || + !test_bit(In_sync, &rs->dev[d].rdev.flags)) && + (++rebuilds_per_group >= copies)) + goto too_many; + } + break; + } + + /* + * When checking "far" and "offset" formats, we need to ensure + * that the device that holds its copy is not also dead or + * being rebuilt. (Note that "far" and "offset" formats only + * support two copies right now. These formats also only ever + * use the 'use_far_sets' variant.) + * + * This check is somewhat complicated by the need to account + * for arrays that are not a multiple of (far) copies. This + * results in the need to treat the last (potentially larger) + * set differently. + */ + group_size = (rs->md.raid_disks / copies); + last_group_start = (rs->md.raid_disks / group_size) - 1; + last_group_start *= group_size; + for (i = 0; i < rs->md.raid_disks; i++) { + if (!(i % copies) && !(i > last_group_start)) rebuilds_per_group = 0; - d = i % rs->md.raid_disks; - if ((!rs->dev[d].rdev.sb_page || - !test_bit(In_sync, &rs->dev[d].rdev.flags)) && + if ((!rs->dev[i].rdev.sb_page || + !test_bit(In_sync, &rs->dev[i].rdev.flags)) && (++rebuilds_per_group >= copies)) - goto too_many; + goto too_many; } break; default: @@ -433,7 +487,7 @@ too_many: * * RAID10-only options: * [raid10_copies <# copies>] Number of copies. (Default: 2) - * [raid10_format ] Layout algorithm. (Default: near) + * [raid10_format ] Layout algorithm. (Default: near) */ static int parse_raid_params(struct raid_set *rs, char **argv, unsigned num_raid_params) @@ -520,7 +574,9 @@ static int parse_raid_params(struct raid_set *rs, char **argv, rs->ti->error = "'raid10_format' is an invalid parameter for this RAID type"; return -EINVAL; } - if (strcmp("near", argv[i])) { + if (strcmp("near", argv[i]) && + strcmp("far", argv[i]) && + strcmp("offset", argv[i])) { rs->ti->error = "Invalid 'raid10_format' value given"; return -EINVAL; } @@ -644,6 +700,15 @@ static int parse_raid_params(struct raid_set *rs, char **argv, return -EINVAL; } + /* + * If the format is not "near", we only support + * two copies at the moment. + */ + if (strcmp("near", raid10_format) && (raid10_copies > 2)) { + rs->ti->error = "Too many copies for given RAID10 format."; + return -EINVAL; + } + /* (Len * #mirrors) / #devices */ sectors_per_dev = rs->ti->len * raid10_copies; sector_div(sectors_per_dev, rs->md.raid_disks); @@ -854,17 +919,30 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev) /* * Reshaping is not currently allowed */ - if ((le32_to_cpu(sb->level) != mddev->level) || - (le32_to_cpu(sb->layout) != mddev->layout) || - (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors)) { - DMERR("Reshaping arrays not yet supported."); + if (le32_to_cpu(sb->level) != mddev->level) { + DMERR("Reshaping arrays not yet supported. (RAID level change)"); + return -EINVAL; + } + if (le32_to_cpu(sb->layout) != mddev->layout) { + DMERR("Reshaping arrays not yet supported. (RAID layout change)"); + DMERR(" 0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout); + DMERR(" Old layout: %s w/ %d copies", + raid10_md_layout_to_format(le32_to_cpu(sb->layout)), + raid10_md_layout_to_copies(le32_to_cpu(sb->layout))); + DMERR(" New layout: %s w/ %d copies", + raid10_md_layout_to_format(mddev->layout), + raid10_md_layout_to_copies(mddev->layout)); + return -EINVAL; + } + if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) { + DMERR("Reshaping arrays not yet supported. (stripe sectors change)"); return -EINVAL; } /* We can only change the number of devices in RAID1 right now */ if ((rs->raid_type->level != 1) && (le32_to_cpu(sb->num_devices) != mddev->raid_disks)) { - DMERR("Reshaping arrays not yet supported."); + DMERR("Reshaping arrays not yet supported. (device count change)"); return -EINVAL; } @@ -1329,7 +1407,8 @@ static int raid_status(struct dm_target *ti, status_type_t type, raid10_md_layout_to_copies(rs->md.layout)); if (rs->print_flags & DMPF_RAID10_FORMAT) - DMEMIT(" raid10_format near"); + DMEMIT(" raid10_format %s", + raid10_md_layout_to_format(rs->md.layout)); DMEMIT(" %d", rs->md.raid_disks); for (i = 0; i < rs->md.raid_disks; i++) { @@ -1420,6 +1499,10 @@ static struct target_type raid_target = { static int __init dm_raid_init(void) { + DMINFO("Loading target version %u.%u.%u", + raid_target.version[0], + raid_target.version[1], + raid_target.version[2]); return dm_register_target(&raid_target); } -- cgit v1.2.3 From a64685399181780998281fe07309a94b25dd24c3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 21 Feb 2013 14:33:17 +1100 Subject: md: fix two bugs when attempting to resize RAID0 array. You cannot resize a RAID0 array (in terms of making the devices bigger), but the code doesn't entirely stop you. So: disable setting of the available size on each device for RAID0 and Linear devices. This must not change as doing so can change the effective layout of data. Make sure that the size that raid0_size() reports is accurate, but rounding devices sizes to chunk sizes. As the device sizes cannot change now, this isn't so important, but it is best to be safe. Without this change: mdadm --grow /dev/md0 -z max mdadm --grow /dev/md0 -Z max then read to the end of the array can cause a BUG in a RAID0 array. These bugs have been present ever since it became possible to resize any device, which is a long time. So the fix is suitable for any -stable kerenl. Cc: stable@vger.kernel.org Signed-off-by: NeilBrown --- drivers/md/md.c | 3 +++ drivers/md/raid0.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index 1e634a68541e..f363135144f6 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2998,6 +2998,9 @@ rdev_size_store(struct md_rdev *rdev, const char *buf, size_t len) } else if (!sectors) sectors = (i_size_read(rdev->bdev->bd_inode) >> 9) - rdev->data_offset; + if (!my_mddev->pers->resize) + /* Cannot change size for RAID0 or Linear etc */ + return -EINVAL; } if (sectors < my_mddev->dev_sectors) return -EINVAL; /* component must fit device */ diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 24b359717a7e..15c8d3505450 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -411,7 +411,8 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks "%s does not support generic reshape\n", __func__); rdev_for_each(rdev, mddev) - array_sectors += rdev->sectors; + array_sectors += (rdev->sectors & + ~(sector_t)(mddev->chunk_sectors-1)); return array_sectors; } -- cgit v1.2.3 From 58ebb34c49fcfcaa029e4b1c1453d92583900f9a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 21 Feb 2013 15:36:38 +1100 Subject: md: raid0: fix error return from create_stripe_zones. Create_stripe_zones returns an error slightly differently to raid0_run and to raid0_takeover_*. The error returned used by the second was wrong and an error would result in mddev->private being set to NULL and sooner or later a crash. So never return NULL, return ERR_PTR(err), not NULL from create_stripe_zones. This bug has been present since 2.6.35 so the fix is suitable for any kernel since then. Cc: stable@vger.kernel.org Signed-off-by: NeilBrown --- drivers/md/raid0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index 15c8d3505450..d9babda582b9 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -289,7 +289,7 @@ abort: kfree(conf->strip_zone); kfree(conf->devlist); kfree(conf); - *private_conf = NULL; + *private_conf = ERR_PTR(err); return err; } -- cgit v1.2.3 From f96c9f305c24a0d4a075e2c75aa6b417aa238687 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 21 Feb 2013 15:50:07 +1100 Subject: md/raid0: improve error message when converting RAID4-with-spares to RAID0 Mentioning "bad disk number -1" exposes irrelevant internal detail. Just say they are inactive and must be removed. Signed-off-by: NeilBrown --- drivers/md/raid0.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index d9babda582b9..0505452de8d6 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c @@ -175,7 +175,13 @@ static int create_strip_zones(struct mddev *mddev, struct r0conf **private_conf) rdev1->new_raid_disk = j; } - if (j < 0 || j >= mddev->raid_disks) { + if (j < 0) { + printk(KERN_ERR + "md/raid0:%s: remove inactive devices before converting to RAID0\n", + mdname(mddev)); + goto abort; + } + if (j >= mddev->raid_disks) { printk(KERN_ERR "md/raid0:%s: bad disk number %d - " "aborting!\n", mdname(mddev), j); goto abort; -- cgit v1.2.3 From ee0b0244030434cdda26777bfb98962447e080cd Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 25 Feb 2013 12:38:29 +1100 Subject: md/raid1,raid10: fix deadlock with freeze_array() When raid1/raid10 needs to fix a read error, it first drains all pending requests by calling freeze_array(). This calls flush_pending_writes() if it needs to sleep, but some writes may be pending in a per-process plug rather than in the per-array request queue. When raid1{,0}_unplug() moves the request from the per-process plug to the per-array request queue (from which flush_pending_writes() can flush them), it needs to wake up freeze_array(), or freeze_array() will never flush them and so it will block forever. So add the requires wake_up() calls. This bug was introduced by commit f54a9d0e59c4bea3db733921ca9147612a6f292c for raid1 and a similar commit for RAID10, and so has been present since linux-3.6. As the bug causes a deadlock I believe this fix is suitable for -stable. Cc: stable@vger.kernel.org (3.6.y 3.7.y 3.8.y) Reported-by: Tregaron Bayly Tested-by: Tregaron Bayly Signed-off-by: NeilBrown --- drivers/md/raid1.c | 1 + drivers/md/raid10.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 6e5d5a5f9cb4..fd86b372692d 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -967,6 +967,7 @@ static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; spin_unlock_irq(&conf->device_lock); + wake_up(&conf->wait_barrier); md_wakeup_thread(mddev->thread); kfree(plug); return; diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 61ed150bd0cf..77b562d18a90 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -1119,6 +1119,7 @@ static void raid10_unplug(struct blk_plug_cb *cb, bool from_schedule) bio_list_merge(&conf->pending_bio_list, &plug->pending); conf->pending_count += plug->pending_cnt; spin_unlock_irq(&conf->device_lock); + wake_up(&conf->wait_barrier); md_wakeup_thread(mddev->thread); kfree(plug); return; -- cgit v1.2.3 From 3a68f19d7afb80f548d016effbc6ed52643a8085 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 20 Dec 2012 18:48:20 +0000 Subject: sfc: Properly sync RX DMA buffer when it is not the last in the page We may currently allocate two RX DMA buffers to a page, and only unmap the page when the second is completed. We do not sync the first RX buffer to be completed; this can result in packet loss or corruption if the last RX buffer completed in a NAPI poll is the first in a page and is not DMA-coherent. (In the middle of a NAPI poll, we will handle the following RX completion and unmap the page *before* looking at the content of the first buffer.) Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/rx.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index d780a0d096b4..a5754916478e 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -236,7 +236,8 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) } static void efx_unmap_rx_buffer(struct efx_nic *efx, - struct efx_rx_buffer *rx_buf) + struct efx_rx_buffer *rx_buf, + unsigned int used_len) { if ((rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.page) { struct efx_rx_page_state *state; @@ -247,6 +248,10 @@ static void efx_unmap_rx_buffer(struct efx_nic *efx, state->dma_addr, efx_rx_buf_size(efx), 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); } } else if (!(rx_buf->flags & EFX_RX_BUF_PAGE) && rx_buf->u.skb) { dma_unmap_single(&efx->pci_dev->dev, rx_buf->dma_addr, @@ -269,7 +274,7 @@ static void efx_free_rx_buffer(struct efx_nic *efx, static void efx_fini_rx_buffer(struct efx_rx_queue *rx_queue, struct efx_rx_buffer *rx_buf) { - efx_unmap_rx_buffer(rx_queue->efx, rx_buf); + efx_unmap_rx_buffer(rx_queue->efx, rx_buf, 0); efx_free_rx_buffer(rx_queue->efx, rx_buf); } @@ -535,10 +540,10 @@ void efx_rx_packet(struct efx_rx_queue *rx_queue, unsigned int index, goto out; } - /* Release card resources - assumes all RX buffers consumed in-order - * per RX queue + /* Release and/or sync DMA mapping - assumes all RX buffers + * consumed in-order per RX queue */ - efx_unmap_rx_buffer(efx, rx_buf); + efx_unmap_rx_buffer(efx, rx_buf, len); /* Prefetch nice and early so data will (hopefully) be in cache by * the time we look at it. -- cgit v1.2.3 From b590ace09d51cd39744e0f7662c5e4a0d1b5d952 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Thu, 10 Jan 2013 23:51:54 +0000 Subject: sfc: Fix efx_rx_buf_offset() in the presence of swiotlb We assume that the mapping between DMA and virtual addresses is done on whole pages, so we can find the page offset of an RX buffer using the lower bits of the DMA address. However, swiotlb maps in units of 2K, breaking this assumption. Add an explicit page_offset field to struct efx_rx_buffer. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/net_driver.h | 4 +++- drivers/net/ethernet/sfc/rx.c | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 2d756c1d7142..0a90abd2421b 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -210,6 +210,7 @@ struct efx_tx_queue { * 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. * @len: Buffer length, in bytes. * @flags: Flags for buffer and packet state. */ @@ -219,7 +220,8 @@ struct efx_rx_buffer { struct sk_buff *skb; struct page *page; } u; - unsigned int len; + u16 page_offset; + u16 len; u16 flags; }; #define EFX_RX_BUF_PAGE 0x0001 diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c index a5754916478e..879ff5849bbd 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -90,11 +90,7 @@ static unsigned int rx_refill_threshold; static inline unsigned int efx_rx_buf_offset(struct efx_nic *efx, struct efx_rx_buffer *buf) { - /* Offset is always within one page, so we don't need to consider - * the page order. - */ - return ((unsigned int) buf->dma_addr & (PAGE_SIZE - 1)) + - efx->type->rx_buffer_hash_size; + return buf->page_offset + efx->type->rx_buffer_hash_size; } static inline unsigned int efx_rx_buf_size(struct efx_nic *efx) { @@ -187,6 +183,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) struct efx_nic *efx = rx_queue->efx; struct efx_rx_buffer *rx_buf; struct page *page; + unsigned int page_offset; struct efx_rx_page_state *state; dma_addr_t dma_addr; unsigned index, count; @@ -211,12 +208,14 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) state->dma_addr = dma_addr; 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->u.page = page; + rx_buf->page_offset = page_offset; rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN; rx_buf->flags = EFX_RX_BUF_PAGE; ++rx_queue->added_count; @@ -227,6 +226,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) /* Use the second half of the page */ get_page(page); dma_addr += (PAGE_SIZE >> 1); + page_offset += (PAGE_SIZE >> 1); ++count; goto split; } -- cgit v1.2.3 From 29c69a4882641285a854d6d03ca5adbba68c0034 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 28 Jan 2013 19:01:06 +0000 Subject: sfc: Detach net device when stopping queues for reconfiguration We must only ever stop TX queues when they are full or the net device is not 'ready' so far as the net core, and specifically the watchdog, is concerned. Otherwise, the watchdog may fire *immediately* if no packets have been added to the queue in the last 5 seconds. The device is ready if all the following are true: (a) It has a qdisc (b) It is marked present (c) It is running (d) The link is reported up (a) and (c) are normally true, and must not be changed by a driver. (d) is under our control, but fake link changes may disturb userland. This leaves (b). We already mark the device absent during reset and self-test, but we need to do the same during MTU changes and ring reallocation. We don't need to do this when the device is brought down because then (c) is already false. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.c b/drivers/net/ethernet/sfc/efx.c index bf57b3cb16ab..0bc00991d310 100644 --- a/drivers/net/ethernet/sfc/efx.c +++ b/drivers/net/ethernet/sfc/efx.c @@ -779,6 +779,7 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) tx_queue->txd.entries); } + efx_device_detach_sync(efx); efx_stop_all(efx); efx_stop_interrupts(efx, true); @@ -832,6 +833,7 @@ out: efx_start_interrupts(efx, true); efx_start_all(efx); + netif_device_attach(efx->net_dev); return rc; rollback: @@ -1641,8 +1643,12 @@ static void efx_stop_all(struct efx_nic *efx) /* Flush efx_mac_work(), refill_workqueue, monitor_work */ efx_flush_all(efx); - /* Stop the kernel transmit interface late, so the watchdog - * timer isn't ticking over the flush */ + /* Stop the kernel transmit interface. This is only valid if + * the device is stopped or detached; otherwise the watchdog + * may fire immediately. + */ + WARN_ON(netif_running(efx->net_dev) && + netif_device_present(efx->net_dev)); netif_tx_disable(efx->net_dev); efx_stop_datapath(efx); @@ -1963,16 +1969,18 @@ static int efx_change_mtu(struct net_device *net_dev, int new_mtu) if (new_mtu > EFX_MAX_MTU) return -EINVAL; - efx_stop_all(efx); - netif_dbg(efx, drv, efx->net_dev, "changing MTU to %d\n", new_mtu); + efx_device_detach_sync(efx); + efx_stop_all(efx); + mutex_lock(&efx->mac_lock); net_dev->mtu = new_mtu; efx->type->reconfigure_mac(efx); mutex_unlock(&efx->mac_lock); efx_start_all(efx); + netif_device_attach(efx->net_dev); return 0; } -- cgit v1.2.3 From 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 25 Feb 2013 16:01:34 +0100 Subject: iwlwifi: always copy first 16 bytes of commands The FH hardware will always write back to the scratch field in commands, even host commands not just TX commands, which can overwrite parts of the command. This is problematic if the command is re-used (with IWL_HCMD_DFL_NOCOPY) and can cause calibration issues. Address this problem by always putting at least the first 16 bytes into the buffer we also use for the command header and therefore make the DMA engine write back into this. For commands that are smaller than 16 bytes also always map enough memory for the DMA engine to write back to. Cc: stable@vger.kernel.org Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 10 ++-- drivers/net/wireless/iwlwifi/pcie/internal.h | 9 ++++ drivers/net/wireless/iwlwifi/pcie/tx.c | 75 +++++++++++++++++++++------- 3 files changed, 71 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 9a0f45ec9e01..10f01793d7a6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -349,25 +349,23 @@ TRACE_EVENT(iwlwifi_dev_rx_data, TRACE_EVENT(iwlwifi_dev_hcmd, TP_PROTO(const struct device *dev, struct iwl_host_cmd *cmd, u16 total_size, - const void *hdr, size_t hdr_len), - TP_ARGS(dev, cmd, total_size, hdr, hdr_len), + struct iwl_cmd_header *hdr), + TP_ARGS(dev, cmd, total_size, hdr), TP_STRUCT__entry( DEV_ENTRY __dynamic_array(u8, hcmd, total_size) __field(u32, flags) ), TP_fast_assign( - int i, offset = hdr_len; + int i, offset = sizeof(*hdr); DEV_ASSIGN; __entry->flags = cmd->flags; - memcpy(__get_dynamic_array(hcmd), hdr, hdr_len); + memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { if (!cmd->len[i]) continue; - if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) - continue; memcpy((u8 *)__get_dynamic_array(hcmd) + offset, cmd->data[i], cmd->len[i]); offset += cmd->len[i]; diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index aa2a39a637dd..3d62e8055352 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -182,6 +182,15 @@ struct iwl_queue { #define TFD_TX_CMD_SLOTS 256 #define TFD_CMD_SLOTS 32 +/* + * The FH will write back to the first TB only, so we need + * to copy some data into the buffer regardless of whether + * it should be mapped or not. This indicates how much to + * copy, even for HCMDs it must be big enough to fit the + * DRAM scratch from the TX cmd, at least 16 bytes. + */ +#define IWL_HCMD_MIN_COPY_SIZE 16 + struct iwl_pcie_txq_entry { struct iwl_device_cmd *cmd; struct iwl_device_cmd *copy_cmd; diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8e9e3212fe78..8b625a7f5685 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1152,10 +1152,12 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, void *dup_buf = NULL; dma_addr_t phys_addr; int idx; - u16 copy_size, cmd_size; + u16 copy_size, cmd_size, dma_size; bool had_nocopy = false; int i; u32 cmd_pos; + const u8 *cmddata[IWL_MAX_CMD_TFDS]; + u16 cmdlen[IWL_MAX_CMD_TFDS]; copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); @@ -1164,8 +1166,23 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + cmddata[i] = cmd->data[i]; + cmdlen[i] = cmd->len[i]; + if (!cmd->len[i]) continue; + + /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ + if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { + int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + + if (copy > cmdlen[i]) + copy = cmdlen[i]; + cmdlen[i] -= copy; + cmddata[i] += copy; + copy_size += copy; + } + if (cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY) { had_nocopy = true; if (WARN_ON(cmd->dataflags[i] & IWL_HCMD_DFL_DUP)) { @@ -1185,7 +1202,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, goto free_dup_buf; } - dup_buf = kmemdup(cmd->data[i], cmd->len[i], + dup_buf = kmemdup(cmddata[i], cmdlen[i], GFP_ATOMIC); if (!dup_buf) return -ENOMEM; @@ -1195,7 +1212,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, idx = -EINVAL; goto free_dup_buf; } - copy_size += cmd->len[i]; + copy_size += cmdlen[i]; } cmd_size += cmd->len[i]; } @@ -1242,14 +1259,31 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* and copy the data that needs to be copied */ cmd_pos = offsetof(struct iwl_device_cmd, payload); + copy_size = sizeof(out_cmd->hdr); for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { - if (!cmd->len[i]) + int copy = 0; + + if (!cmd->len) continue; - if (cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | - IWL_HCMD_DFL_DUP)) - break; - memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], cmd->len[i]); - cmd_pos += cmd->len[i]; + + /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ + if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { + copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + + if (copy > cmd->len[i]) + copy = cmd->len[i]; + } + + /* copy everything if not nocopy/dup */ + if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | + IWL_HCMD_DFL_DUP))) + copy = cmd->len[i]; + + if (copy) { + memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy); + cmd_pos += copy; + copy_size += copy; + } } WARN_ON_ONCE(txq->entries[idx].copy_cmd); @@ -1275,7 +1309,14 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); - phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, copy_size, + /* + * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must + * still map at least that many bytes for the hardware to write back to. + * We have enough space, so that's not a problem. + */ + dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE); + + phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size, DMA_BIDIRECTIONAL); if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { idx = -ENOMEM; @@ -1283,14 +1324,15 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, } dma_unmap_addr_set(out_meta, mapping, phys_addr); - dma_unmap_len_set(out_meta, len, copy_size); + dma_unmap_len_set(out_meta, len, dma_size); iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); + /* map the remaining (adjusted) nocopy/dup fragments */ for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { - const void *data = cmd->data[i]; + const void *data = cmddata[i]; - if (!cmd->len[i]) + if (!cmdlen[i]) continue; if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | IWL_HCMD_DFL_DUP))) @@ -1298,7 +1340,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) data = dup_buf; phys_addr = dma_map_single(trans->dev, (void *)data, - cmd->len[i], DMA_BIDIRECTIONAL); + cmdlen[i], DMA_BIDIRECTIONAL); if (dma_mapping_error(trans->dev, phys_addr)) { iwl_pcie_tfd_unmap(trans, out_meta, &txq->tfds[q->write_ptr], @@ -1307,7 +1349,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, goto out; } - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmd->len[i], 0); + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0); } out_meta->flags = cmd->flags; @@ -1317,8 +1359,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, txq->need_update = 1; - trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, - &out_cmd->hdr, copy_size); + trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); /* start timer if queue currently empty */ if (q->read_ptr == q->write_ptr && trans_pcie->wd_timeout) -- cgit v1.2.3 From 38a12b5b029dec6e6dad1b5d3269b4c356c44c0e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 22 Feb 2013 14:07:56 +0100 Subject: iwlwifi: mvm: fix AP/GO mode station removal When stations are removed while packets are in the queue, we drain the queues first, and then remove the stations. If this happens in AP mode while the interface is removed the MAC context might be removed from the firmware before we removed the station(s), resulting in a SYSASSERT 3421. This is because we remove the MAC context from the FW in stop_ap(), but only flush the station drain work later in remove_interface(). Refactor the code a bit to have a common MAC context removal preparation first to solve this. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/mac80211.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index e8264e11b12d..7e169b085afe 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c @@ -557,11 +557,9 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, return ret; } -static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, - struct ieee80211_vif *vif) +static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm, + struct ieee80211_vif *vif) { - struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); - struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); u32 tfd_msk = 0, ac; for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) @@ -594,12 +592,21 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, */ flush_work(&mvm->sta_drained_wk); } +} + +static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, + struct ieee80211_vif *vif) +{ + struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); + struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + + iwl_mvm_prepare_mac_removal(mvm, vif); mutex_lock(&mvm->mutex); /* * For AP/GO interface, the tear down of the resources allocated to the - * interface should be handled as part of the bss_info_changed flow. + * interface is be handled as part of the stop_ap flow. */ if (vif->type == NL80211_IFTYPE_AP) { iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); @@ -763,6 +770,8 @@ static void iwl_mvm_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); + iwl_mvm_prepare_mac_removal(mvm, vif); + mutex_lock(&mvm->mutex); mvmvif->ap_active = false; -- cgit v1.2.3 From 0237c11044b3670adcbe80cd6dd721285347f497 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 26 Feb 2013 04:06:20 +0000 Subject: drivers: net: ethernet: cpsw: consider number of slaves in interation Make cpsw_add_default_vlan() look at the actual number of slaves for its iteration, so boards with less than 2 slaves don't ooops at boot. Signed-off-by: Daniel Mack Cc: Mugunthan V N Cc: David S. Miller Acked-by: Mugunthan V N Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 7e93df6585e7..01ffbc486982 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -731,7 +731,7 @@ static inline void cpsw_add_default_vlan(struct cpsw_priv *priv) writel(vlan, &priv->host_port_regs->port_vlan); - for (i = 0; i < 2; i++) + for (i = 0; i < priv->data.slaves; i++) slave_write(priv->slaves + i, vlan, reg); cpsw_ale_add_vlan(priv->ale, vlan, ALE_ALL_PORTS << port, -- cgit v1.2.3 From 6c8c4e4c24b9f6cee3d356a51e4a7f2af787a49b Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Mon, 25 Feb 2013 22:26:15 +0000 Subject: bond: check if slave count is 0 in case when deciding to take slave's mac in bond_enslave(), check slave_cnt before actually using slave address. introduced by: commit 409cc1f8a41 (bond: have random dev address by default instead of zeroes) Reported-by: Greg Rose Signed-off-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 11d01d67b3f5..7bd068a6056a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1629,7 +1629,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) /* If this is the first slave, then we need to set the master's hardware * address to be the same as the slave's. */ - if (bond->dev_addr_from_first) + if (bond->slave_cnt == 0 && bond->dev_addr_from_first) bond_set_dev_addr(bond->dev, slave_dev); new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL); -- cgit v1.2.3 From 114a6f8b52163c0232fbcd7f3808ff04dc61a9b5 Mon Sep 17 00:00:00 2001 From: Marina Makienko Date: Mon, 25 Feb 2013 22:26:50 +0000 Subject: isdn: hisax: add missing usb_free_urb Add missing usb_free_urb() on failure path in st5481_setup_usb(). Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Marina Makienko Signed-off-by: David S. Miller --- drivers/isdn/hisax/st5481_usb.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/st5481_usb.c b/drivers/isdn/hisax/st5481_usb.c index 017c67ea3f4c..ead0a4fb7448 100644 --- a/drivers/isdn/hisax/st5481_usb.c +++ b/drivers/isdn/hisax/st5481_usb.c @@ -294,13 +294,13 @@ int st5481_setup_usb(struct st5481_adapter *adapter) // Allocate URBs and buffers for interrupt endpoint urb = usb_alloc_urb(0, GFP_KERNEL); if (!urb) { - return -ENOMEM; + goto err1; } intr->urb = urb; buf = kmalloc(INT_PKT_SIZE, GFP_KERNEL); if (!buf) { - return -ENOMEM; + goto err2; } endpoint = &altsetting->endpoint[EP_INT-1]; @@ -313,6 +313,14 @@ int st5481_setup_usb(struct st5481_adapter *adapter) endpoint->desc.bInterval); return 0; +err2: + usb_free_urb(intr->urb); + intr->urb = NULL; +err1: + usb_free_urb(ctrl->urb); + ctrl->urb = NULL; + + return -ENOMEM; } /* -- cgit v1.2.3 From f444eb10d537c776ce82fbcd07733d75f45346f1 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2013 12:04:18 +0100 Subject: iwlwifi: fix wakeup status query and packet reporting The wakeup packet in the status response is padded out to a multiple of 4 bytes by the firmware for transfer to the host, take that into account when checking the length of the command. Also, the reported wakeup packet includes the FCS but the userspace API doesn't, so remove that. If it is a data packet it is reported as an 802.3 packet but I forgot to take into account and remove the encryption head/tail, fix all of that as well. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/d3.c | 104 ++++++++++++++++++++++++--------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 4 ++ 2 files changed, 81 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c index c64d864799cd..994c8c263dc0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/d3.c +++ b/drivers/net/wireless/iwlwifi/mvm/d3.c @@ -61,6 +61,7 @@ * *****************************************************************************/ +#include #include #include #include "iwl-modparams.h" @@ -192,6 +193,11 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, sizeof(wkc), &wkc); data->error = ret != 0; + mvm->ptk_ivlen = key->iv_len; + mvm->ptk_icvlen = key->icv_len; + mvm->gtk_ivlen = key->iv_len; + mvm->gtk_icvlen = key->icv_len; + /* don't upload key again */ goto out_unlock; } @@ -304,9 +310,13 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, */ if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) { key->hw_key_idx = 0; + mvm->ptk_ivlen = key->iv_len; + mvm->ptk_icvlen = key->icv_len; } else { data->gtk_key_idx++; key->hw_key_idx = data->gtk_key_idx; + mvm->gtk_ivlen = key->iv_len; + mvm->gtk_icvlen = key->icv_len; } ret = iwl_mvm_set_sta_key(mvm, vif, sta, key, true); @@ -649,6 +659,11 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) /* We reprogram keys and shouldn't allocate new key indices */ memset(mvm->fw_key_table, 0, sizeof(mvm->fw_key_table)); + mvm->ptk_ivlen = 0; + mvm->ptk_icvlen = 0; + mvm->ptk_ivlen = 0; + mvm->ptk_icvlen = 0; + /* * The D3 firmware still hardcodes the AP station ID for the * BSS we're associated with as 0. As a result, we have to move @@ -783,7 +798,6 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, struct iwl_wowlan_status *status; u32 reasons; int ret, len; - bool pkt8023 = false; struct sk_buff *pkt = NULL; iwl_trans_read_mem_bytes(mvm->trans, base, @@ -824,7 +838,8 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, status = (void *)cmd.resp_pkt->data; if (len - sizeof(struct iwl_cmd_header) != - sizeof(*status) + le32_to_cpu(status->wake_packet_bufsize)) { + sizeof(*status) + + ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4)) { IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); goto out; } @@ -836,61 +851,96 @@ static void iwl_mvm_query_wakeup_reasons(struct iwl_mvm *mvm, goto report; } - if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_MAGIC_PACKET) wakeup.magic_pkt = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_PATTERN) wakeup.pattern_idx = le16_to_cpu(status->pattern_number); - pkt8023 = true; - } if (reasons & (IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_MISSED_BEACON | IWL_WOWLAN_WAKEUP_BY_DISCONNECTION_ON_DEAUTH)) wakeup.disconnect = true; - if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_GTK_REKEY_FAILURE) wakeup.gtk_rekey_failure = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_RFKILL_DEASSERTED) wakeup.rfkill_release = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_EAPOL_REQUEST) wakeup.eap_identity_req = true; - pkt8023 = true; - } - if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) { + if (reasons & IWL_WOWLAN_WAKEUP_BY_FOUR_WAY_HANDSHAKE) wakeup.four_way_handshake = true; - pkt8023 = true; - } if (status->wake_packet_bufsize) { - u32 pktsize = le32_to_cpu(status->wake_packet_bufsize); - u32 pktlen = le32_to_cpu(status->wake_packet_length); + int pktsize = le32_to_cpu(status->wake_packet_bufsize); + int pktlen = le32_to_cpu(status->wake_packet_length); + const u8 *pktdata = status->wake_packet; + struct ieee80211_hdr *hdr = (void *)pktdata; + int truncated = pktlen - pktsize; + + /* this would be a firmware bug */ + if (WARN_ON_ONCE(truncated < 0)) + truncated = 0; + + if (ieee80211_is_data(hdr->frame_control)) { + int hdrlen = ieee80211_hdrlen(hdr->frame_control); + int ivlen = 0, icvlen = 4; /* also FCS */ - if (pkt8023) { pkt = alloc_skb(pktsize, GFP_KERNEL); if (!pkt) goto report; - memcpy(skb_put(pkt, pktsize), status->wake_packet, - pktsize); + + memcpy(skb_put(pkt, hdrlen), pktdata, hdrlen); + pktdata += hdrlen; + pktsize -= hdrlen; + + if (ieee80211_has_protected(hdr->frame_control)) { + if (is_multicast_ether_addr(hdr->addr1)) { + ivlen = mvm->gtk_ivlen; + icvlen += mvm->gtk_icvlen; + } else { + ivlen = mvm->ptk_ivlen; + icvlen += mvm->ptk_icvlen; + } + } + + /* if truncated, FCS/ICV is (partially) gone */ + if (truncated >= icvlen) { + icvlen = 0; + truncated -= icvlen; + } else { + icvlen -= truncated; + truncated = 0; + } + + pktsize -= ivlen + icvlen; + pktdata += ivlen; + + memcpy(skb_put(pkt, pktsize), pktdata, pktsize); + if (ieee80211_data_to_8023(pkt, vif->addr, vif->type)) goto report; wakeup.packet = pkt->data; wakeup.packet_present_len = pkt->len; - wakeup.packet_len = pkt->len - (pktlen - pktsize); + wakeup.packet_len = pkt->len - truncated; wakeup.packet_80211 = false; } else { + int fcslen = 4; + + if (truncated >= 4) { + truncated -= 4; + fcslen = 0; + } else { + fcslen -= truncated; + truncated = 0; + } + pktsize -= fcslen; wakeup.packet = status->wake_packet; wakeup.packet_present_len = pktsize; - wakeup.packet_len = pktlen; + wakeup.packet_len = pktlen - truncated; wakeup.packet_80211 = true; } } diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 4e339ccfa800..537711b10478 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -327,6 +327,10 @@ struct iwl_mvm { struct led_classdev led; struct ieee80211_vif *p2p_device_vif; + +#ifdef CONFIG_PM_SLEEP + int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; +#endif }; /* Extract MVM priv from op_mode and _hw */ -- cgit v1.2.3 From e477598351a40769f5b46ccea78479a1aad6f161 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Tue, 12 Feb 2013 09:49:00 +0200 Subject: iwlwifi: mvm: Remove testing of static PIC in PhyDB The PIC was supposed to be a small signature appended to the PhyDB data, but the signature isn't really static and thus attempting to check it just causes the warnings spuriously so remove them. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-phy-db.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-phy-db.c b/drivers/net/wireless/iwlwifi/iwl-phy-db.c index 14fc8d39fc28..3392011a8768 100644 --- a/drivers/net/wireless/iwlwifi/iwl-phy-db.c +++ b/drivers/net/wireless/iwlwifi/iwl-phy-db.c @@ -136,12 +136,6 @@ struct iwl_calib_res_notif_phy_db { u8 data[]; } __packed; -#define IWL_PHY_DB_STATIC_PIC cpu_to_le32(0x21436587) -static inline void iwl_phy_db_test_pic(__le32 pic) -{ - WARN_ON(IWL_PHY_DB_STATIC_PIC != pic); -} - struct iwl_phy_db *iwl_phy_db_init(struct iwl_trans *trans) { struct iwl_phy_db *phy_db = kzalloc(sizeof(struct iwl_phy_db), @@ -260,11 +254,6 @@ int iwl_phy_db_set_section(struct iwl_phy_db *phy_db, struct iwl_rx_packet *pkt, (size - CHANNEL_NUM_SIZE) / phy_db->channel_num; } - /* Test PIC */ - if (type != IWL_PHY_DB_CFG) - iwl_phy_db_test_pic(*(((__le32 *)phy_db_notif->data) + - (size / sizeof(__le32)) - 1)); - IWL_DEBUG_INFO(phy_db->trans, "%s(%d): [PHYDB]SET: Type %d , Size: %d\n", __func__, __LINE__, type, size); @@ -372,11 +361,6 @@ int iwl_phy_db_get_section_data(struct iwl_phy_db *phy_db, *size = entry->size; } - /* Test PIC */ - if (type != IWL_PHY_DB_CFG) - iwl_phy_db_test_pic(*(((__le32 *)*data) + - (*size / sizeof(__le32)) - 1)); - IWL_DEBUG_INFO(phy_db->trans, "%s(%d): [PHYDB] GET: Type %d , Size: %d\n", __func__, __LINE__, type, *size); -- cgit v1.2.3 From e70ab977991964a5a7ad1182799451d067e62669 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 25 Feb 2013 21:32:25 +0000 Subject: proc connector: reject unprivileged listener bumps While PROC_CN_MCAST_LISTEN/IGNORE is entirely advisory, it was possible for an unprivileged user to turn off notifications for all listeners by sending PROC_CN_MCAST_IGNORE. Instead, require the same privileges as required for a multicast bind. Signed-off-by: Kees Cook Cc: Evgeniy Polyakov Cc: Matt Helsley Cc: stable@vger.kernel.org Acked-by: Evgeniy Polyakov Acked-by: Matt Helsley Signed-off-by: David S. Miller --- drivers/connector/cn_proc.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index fce2000eec31..1110478dd0fd 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -313,6 +313,12 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, (task_active_pid_ns(current) != &init_pid_ns)) return; + /* Can only change if privileged. */ + if (!capable(CAP_NET_ADMIN)) { + err = EPERM; + goto out; + } + mc_op = (enum proc_cn_mcast_op *)msg->data; switch (*mc_op) { case PROC_CN_MCAST_LISTEN: @@ -325,6 +331,8 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, err = EINVAL; break; } + +out: cn_proc_ack(err, msg->seq, msg->ack); } -- cgit v1.2.3 From e2593fcde1d906b26b81b38755749f7427f3439f Mon Sep 17 00:00:00 2001 From: Dmitry Kravkov Date: Wed, 27 Feb 2013 00:04:59 +0000 Subject: bnx2x: fix UDP checksum for 57710/57711. Since commit 86564c3f "bnx2x: Remove many sparse warnings" UDP csum offload is broken for 57710/57711. Fix return value. Signed-off-by: Dmitry Kravkov CC: Ariel Elior CC: Yuval Mintz Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c index ecac04a3687c..a923bc4d5a1f 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -3142,7 +3142,7 @@ static inline __le16 bnx2x_csum_fix(unsigned char *t_header, u16 csum, s8 fix) tsum = ~csum_fold(csum_add((__force __wsum) csum, csum_partial(t_header, -fix, 0))); - return bswab16(csum); + return bswab16(tsum); } static inline u32 bnx2x_xmit_type(struct bnx2x *bp, struct sk_buff *skb) -- cgit v1.2.3 From 1f84eab4ad73bcb7d779cba65291fe62909e373f Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 27 Feb 2013 03:08:58 +0000 Subject: net: cdc_ncm: tag Huawei devices (e.g. E5331) with FLAG_WWAN MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tag all Huawei NCM devices as WWAN modems, as we don't know of any which are not. This is necessary for userspace clients to know that the device requires further setup on e.g. an AT-capable serial ports before connectivity is available. Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/cdc_ncm.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 4a8c25a22294..61b74a2b89ac 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -1213,6 +1213,14 @@ static const struct usb_device_id cdc_devs[] = { .driver_info = (unsigned long) &wwan_info, }, + /* tag Huawei devices as wwan */ + { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, + USB_CLASS_COMM, + USB_CDC_SUBCLASS_NCM, + USB_CDC_PROTO_NONE), + .driver_info = (unsigned long)&wwan_info, + }, + /* Huawei NCM devices disguised as vendor specific */ { USB_VENDOR_AND_INTERFACE_INFO(0x12d1, 0xff, 0x02, 0x16), .driver_info = (unsigned long)&wwan_info, -- cgit v1.2.3 From 45af3fb4a018ef84bf1c9f2dfbd887a41242e77f Mon Sep 17 00:00:00 2001 From: Glen Turner Date: Wed, 27 Feb 2013 04:32:36 +0000 Subject: usb/net/asix_devices: Add USBNET HG20F9 ethernet dongle This USB ethernet adapter was purchased in anodyne packaging from the computer store adjacent to linux.conf.au 2013 in Canberra (Australia). A web search shows other recent purchasers in Lancaster (UK) and Seattle (USA). Just like an emergent virus, our age of e-commerce and airmail allows underdocumented hardware to spread around the world instantly using the vector of ridiculously low prices. Paige Thompson, infected via eBay, discovered that the HG20F9 is a copy of the Asix 88772B; many viruses copy the RNA of other viruses. See Paige's work at . This patch uses her discovery to update the restructured Asix driver in the current kernel. Just as some viruses inhabit seemingly-healthy cells, the HG20F9 uses the Vendor ID 0x066b assigned to Linksys Inc. For the present there is no clash of Product ID 0x20f9. Signed-off-by: Glen Turner Signed-off-by: David S. Miller --- drivers/net/usb/asix_devices.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/asix_devices.c b/drivers/net/usb/asix_devices.c index 2205dbc8d32f..709753469099 100644 --- a/drivers/net/usb/asix_devices.c +++ b/drivers/net/usb/asix_devices.c @@ -924,6 +924,29 @@ static const struct driver_info ax88178_info = { .tx_fixup = asix_tx_fixup, }; +/* + * USBLINK 20F9 "USB 2.0 LAN" USB ethernet adapter, typically found in + * no-name packaging. + * USB device strings are: + * 1: Manufacturer: USBLINK + * 2: Product: HG20F9 USB2.0 + * 3: Serial: 000003 + * Appears to be compatible with Asix 88772B. + */ +static const struct driver_info hg20f9_info = { + .description = "HG20F9 USB 2.0 Ethernet", + .bind = ax88772_bind, + .unbind = ax88772_unbind, + .status = asix_status, + .link_reset = ax88772_link_reset, + .reset = ax88772_reset, + .flags = FLAG_ETHER | FLAG_FRAMING_AX | FLAG_LINK_INTR | + FLAG_MULTI_PACKET, + .rx_fixup = asix_rx_fixup_common, + .tx_fixup = asix_tx_fixup, + .data = FLAG_EEPROM_MAC, +}; + extern const struct driver_info ax88172a_info; static const struct usb_device_id products [] = { @@ -1063,6 +1086,14 @@ static const struct usb_device_id products [] = { /* ASIX 88172a demo board */ USB_DEVICE(0x0b95, 0x172a), .driver_info = (unsigned long) &ax88172a_info, +}, { + /* + * USBLINK HG20F9 "USB 2.0 LAN" + * Appears to have gazumped Linksys's manufacturer ID but + * doesn't (yet) conflict with any known Linksys product. + */ + USB_DEVICE(0x066b, 0x20f9), + .driver_info = (unsigned long) &hg20f9_info, }, { }, // END }; -- cgit v1.2.3 From a3d63cadbad97671d740a9698acc2c95d1ca6e79 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 22 Feb 2013 21:09:17 +0100 Subject: ath9k: fix RSSI dummy marker value RSSI is being stored internally as s8 in several places. The indication of an unset RSSI value, ATH_RSSI_DUMMY_MARKER, was supposed to have been set to 127, but ended up being set to 0x127 because of a code cleanup mistake. This could lead to invalid signal strength values in a few places. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org 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..050ca4a4850d 100644 --- a/drivers/net/wireless/ath/ath9k/common.h +++ b/drivers/net/wireless/ath/ath9k/common.h @@ -27,7 +27,7 @@ #define WME_MAX_BA WME_BA_BMP_SIZE #define ATH_TID_MAX_BUFS (2 * WME_MAX_BA) -#define ATH_RSSI_DUMMY_MARKER 0x127 +#define ATH_RSSI_DUMMY_MARKER 127 #define ATH_RSSI_LPF_LEN 10 #define RSSI_LPF_THRESHOLD -20 #define ATH_RSSI_EP_MULTIPLIER (1<<7) -- cgit v1.2.3 From 838f427955dcfd16858b0108ce29029da0d56a4e Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 22 Feb 2013 21:37:25 +0100 Subject: ath9k_htc: fix signal strength handling issues The ath9k commit 2ef167557c0a26c88162ecffb017bfcc51eb7b29 (ath9k: fix signal strength reporting issues) fixed an issue where the reported per-frame signal strength reported to mac80211 was being overwritten with an internal average. The same issue is also present in ath9k_htc. In addition to preventing the driver from overwriting the value, this commit also ensures that the internal average (which is used for ANI) only tracks beacons of the AP that we're connected to. Signed-off-by: Felix Fietkau Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/htc.h | 1 + drivers/net/wireless/ath/ath9k/htc_drv_txrx.c | 18 +++++++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 96bfb18078fa..d3b099d7898b 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c index b6a5a08810b8..878862178e06 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c @@ -1067,15 +1067,19 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv, last_rssi = priv->rx.last_rssi; - if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) - rxbuf->rxstatus.rs_rssi = ATH_EP_RND(last_rssi, - ATH_RSSI_EP_MULTIPLIER); + if (ieee80211_is_beacon(hdr->frame_control) && + !is_zero_ether_addr(common->curbssid) && + ether_addr_equal(hdr->addr3, common->curbssid)) { + s8 rssi = rxbuf->rxstatus.rs_rssi; - if (rxbuf->rxstatus.rs_rssi < 0) - rxbuf->rxstatus.rs_rssi = 0; + if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER)) + rssi = ATH_EP_RND(last_rssi, ATH_RSSI_EP_MULTIPLIER); - if (ieee80211_is_beacon(fc)) - priv->ah->stats.avgbrssi = rxbuf->rxstatus.rs_rssi; + if (rssi < 0) + rssi = 0; + + priv->ah->stats.avgbrssi = rssi; + } rx_status->mactime = be64_to_cpu(rxbuf->rxstatus.rs_tstamp); rx_status->band = hw->conf.channel->band; -- cgit v1.2.3 From f45dd363bee071a62e32398a0ae4a0214b8029eb Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Sat, 23 Feb 2013 23:30:22 +0100 Subject: bcma: init spin lock This spin lock was not initialized. Signed-off-by: Hauke Mehrtens Signed-off-by: John W. Linville --- drivers/bcma/driver_pci_host.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/bcma/driver_pci_host.c b/drivers/bcma/driver_pci_host.c index 221f8bb76390..25de38719684 100644 --- a/drivers/bcma/driver_pci_host.c +++ b/drivers/bcma/driver_pci_host.c @@ -405,6 +405,8 @@ void __devinit bcma_core_pci_hostmode_init(struct bcma_drv_pci *pc) return; } + spin_lock_init(&pc_host->cfgspace_lock); + pc->host_controller = pc_host; pc_host->pci_controller.io_resource = &pc_host->io_resource; pc_host->pci_controller.mem_resource = &pc_host->mem_resource; -- cgit v1.2.3 From 3412f2f086ea7531378fabe756bd4a1109994ae6 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Mon, 25 Feb 2013 20:51:07 +0100 Subject: ath9k_hw: improve reset reliability after errors On many different chips, important aspects of the MAC state are not fully cleared by a warm reset. This can show up as tx/rx hangs, those annoying "DMA failed to stop in 10 ms..." messages or other quirks. On AR933x, the chip can occasionally get stuck in a way that only a driver unload/reload or a reboot would bring it back to life. With this patch, a full reset is issued when bringing the chip out of FULL-SLEEP state (after idle), or if either Rx or Tx was not shut down properly. This makes the DMA related error messages disappear completely in my tests on AR933x, and the chip does not get stuck anymore. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/hw.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 42cf3c7f1e25..7b485e4d104c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c @@ -1463,7 +1463,9 @@ static bool ath9k_hw_chip_reset(struct ath_hw *ah, reset_type = ATH9K_RESET_POWER_ON; else reset_type = ATH9K_RESET_COLD; - } + } else if (ah->chip_fullsleep || REG_READ(ah, AR_Q_TXE) || + (REG_READ(ah, AR_CR) & AR_CR_RXE)) + reset_type = ATH9K_RESET_COLD; if (!ath9k_hw_set_reset_reg(ah, reset_type)) return false; -- cgit v1.2.3 From 3e7a4ff7c5b6423ddb644df9c41b8b6d2fb79d30 Mon Sep 17 00:00:00 2001 From: Avinash Patil Date: Mon, 25 Feb 2013 16:01:34 -0800 Subject: mwifiex: correct sleep delay counter Maximum delay for waking up card is 50 ms. Because of typo in counter, this delay goes to 500ms. This patch fixes the bug. Cc: # 3.2+ Signed-off-by: Avinash Patil Signed-off-by: Amitkumar Karwar Signed-off-by: Yogesh Ashok Powar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/pcie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c index 35c79722c361..5c395e2e6a2b 100644 --- a/drivers/net/wireless/mwifiex/pcie.c +++ b/drivers/net/wireless/mwifiex/pcie.c @@ -302,7 +302,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter) i++; usleep_range(10, 20); /* 50ms max wait */ - if (i == 50000) + if (i == 5000) break; } -- cgit v1.2.3 From 6ef9e2f6d12ce9e2120916804d2ddd46b954a70b Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Tue, 26 Feb 2013 16:09:55 +0100 Subject: rt2x00: error in configurations with mesh support disabled If CONFIG_MAC80211_MESH is not set, cfg80211 will now allow advertising interface combinations with NL80211_IFTYPE_MESH_POINT present. Add appropriate ifdefs to avoid running into errors. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/rt2x00dev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 1031db66474a..189744db65e0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c @@ -1236,8 +1236,10 @@ static inline void rt2x00lib_set_if_combinations(struct rt2x00_dev *rt2x00dev) */ if_limit = &rt2x00dev->if_limits_ap; if_limit->max = rt2x00dev->ops->max_ap_intf; - if_limit->types = BIT(NL80211_IFTYPE_AP) | - BIT(NL80211_IFTYPE_MESH_POINT); + if_limit->types = BIT(NL80211_IFTYPE_AP); +#ifdef CONFIG_MAC80211_MESH + if_limit->types |= BIT(NL80211_IFTYPE_MESH_POINT); +#endif /* * Build up AP interface combinations structure. @@ -1309,7 +1311,9 @@ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) rt2x00dev->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | +#ifdef CONFIG_MAC80211_MESH BIT(NL80211_IFTYPE_MESH_POINT) | +#endif BIT(NL80211_IFTYPE_WDS); rt2x00dev->hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; -- cgit v1.2.3 From 466026989f112e0546ca39ab00a759af82dbe83a Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Tue, 26 Feb 2013 12:58:35 -0800 Subject: libertas: fix crash for SD8688 For SD8688, FUNC_INIT command is queued before fw_ready flag is set. This causes the following crash as lbs_thread blocks any command if fw_ready is not set. [ 209.338953] [] (__schedule+0x610/0x764) from [] (__lbs_cmd+0xb8/0x130 [libertas]) [ 209.348340] [] (__lbs_cmd+0xb8/0x130 [libertas]) from [] (if_sdio_finish_power_on+0xec/0x1b0 [libertas_sdio]) [ 209.360136] [] (if_sdio_finish_power_on+0xec/0x1b0 [libertas_sdio]) from [] (if_sdio_power_on+0x18c/0x20c [libertas_sdio]) [ 209.373052] [] (if_sdio_power_on+0x18c/0x20c [libertas_sdio]) from [] (if_sdio_probe+0x200/0x31c [libertas_sdio]) [ 209.385316] [] (if_sdio_probe+0x200/0x31c [libertas_sdio]) from [] (sdio_bus_probe+0x94/0xfc [mmc_core]) [ 209.396748] [] (sdio_bus_probe+0x94/0xfc [mmc_core]) from [] (driver_probe_device+0x12c/0x348) [ 209.407214] [] (driver_probe_device+0x12c/0x348) from [] (__driver_attach+0x78/0x9c) [ 209.416798] [] (__driver_attach+0x78/0x9c) from [] (bus_for_each_dev+0x50/0x88) [ 209.425946] [] (bus_for_each_dev+0x50/0x88) from [] (bus_add_driver+0x108/0x268) [ 209.435180] [] (bus_add_driver+0x108/0x268) from [] (driver_register+0xa4/0x134) [ 209.444426] [] (driver_register+0xa4/0x134) from [] (if_sdio_init_module+0x1c/0x3c [libertas_sdio]) [ 209.455339] [] (if_sdio_init_module+0x1c/0x3c [libertas_sdio]) from [] (do_one_initcall+0x98/0x174) [ 209.466236] [] (do_one_initcall+0x98/0x174) from [] (load_module+0x1c5c/0x1f80) [ 209.475390] [] (load_module+0x1c5c/0x1f80) from [] (sys_init_module+0x104/0x128) [ 209.484632] [] (sys_init_module+0x104/0x128) from [] (ret_fast_syscall+0x0/0x38) Fix it by setting fw_ready flag prior to queuing FUNC_INIT command. Cc: # 3.5+ Reported-by: Lubomir Rintel Tested-by: Lubomir Rintel Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/libertas/if_sdio.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index 739309e70d8b..45578335e420 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c @@ -825,6 +825,11 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card) sdio_release_host(func); + /* Set fw_ready before queuing any commands so that + * lbs_thread won't block from sending them to firmware. + */ + priv->fw_ready = 1; + /* * FUNC_INIT is required for SD8688 WLAN/BT multiple functions */ @@ -839,7 +844,6 @@ static void if_sdio_finish_power_on(struct if_sdio_card *card) netdev_alert(priv->dev, "CMD_FUNC_INIT cmd failed\n"); } - priv->fw_ready = 1; wake_up(&card->pwron_waitq); if (!card->started) { -- cgit v1.2.3 From 51acbcec6c42b24482bac18e42befc822524535d Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 28 Feb 2013 09:08:34 +1100 Subject: md: remove CONFIG_MULTICORE_RAID456 This doesn't seem to actually help and we have an alternate multi-threading approach waiting in the wings, so just get rid of this config option and associated code. As a bonus, we remove one use of CONFIG_EXPERIMENTAL Cc: Dan Williams Cc: Kees Cook Signed-off-by: NeilBrown --- drivers/md/Kconfig | 11 ----------- drivers/md/raid5.c | 38 +------------------------------------- 2 files changed, 1 insertion(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 91a02eeeb319..9a10313d0670 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -154,17 +154,6 @@ config MD_RAID456 If unsure, say Y. -config MULTICORE_RAID456 - bool "RAID-4/RAID-5/RAID-6 Multicore processing (EXPERIMENTAL)" - depends on MD_RAID456 - depends on SMP - depends on EXPERIMENTAL - ---help--- - Enable the raid456 module to dispatch per-stripe raid operations to a - thread pool. - - If unsure, say N. - config MD_MULTIPATH tristate "Multipath I/O support" depends on BLK_DEV_MD diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 19d77a026639..35031c8b2d02 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -1406,7 +1406,7 @@ static void ops_run_check_pq(struct stripe_head *sh, struct raid5_percpu *percpu &sh->ops.zero_sum_result, percpu->spare_page, &submit); } -static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request) +static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) { int overlap_clear = 0, i, disks = sh->disks; struct dma_async_tx_descriptor *tx = NULL; @@ -1471,36 +1471,6 @@ static void __raid_run_ops(struct stripe_head *sh, unsigned long ops_request) put_cpu(); } -#ifdef CONFIG_MULTICORE_RAID456 -static void async_run_ops(void *param, async_cookie_t cookie) -{ - struct stripe_head *sh = param; - unsigned long ops_request = sh->ops.request; - - clear_bit_unlock(STRIPE_OPS_REQ_PENDING, &sh->state); - wake_up(&sh->ops.wait_for_ops); - - __raid_run_ops(sh, ops_request); - release_stripe(sh); -} - -static void raid_run_ops(struct stripe_head *sh, unsigned long ops_request) -{ - /* since handle_stripe can be called outside of raid5d context - * we need to ensure sh->ops.request is de-staged before another - * request arrives - */ - wait_event(sh->ops.wait_for_ops, - !test_and_set_bit_lock(STRIPE_OPS_REQ_PENDING, &sh->state)); - sh->ops.request = ops_request; - - atomic_inc(&sh->count); - async_schedule(async_run_ops, sh); -} -#else -#define raid_run_ops __raid_run_ops -#endif - static int grow_one_stripe(struct r5conf *conf) { struct stripe_head *sh; @@ -1509,9 +1479,6 @@ static int grow_one_stripe(struct r5conf *conf) return 0; sh->raid_conf = conf; - #ifdef CONFIG_MULTICORE_RAID456 - init_waitqueue_head(&sh->ops.wait_for_ops); - #endif spin_lock_init(&sh->stripe_lock); @@ -1630,9 +1597,6 @@ static int resize_stripes(struct r5conf *conf, int newsize) break; nsh->raid_conf = conf; - #ifdef CONFIG_MULTICORE_RAID456 - init_waitqueue_head(&nsh->ops.wait_for_ops); - #endif spin_lock_init(&nsh->stripe_lock); list_add(&nsh->lru, &newstripes); -- cgit v1.2.3 From f3378b48705154b9089affb2d2e939622aea68f1 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 28 Feb 2013 11:59:03 +1100 Subject: md: expedite metadata update when switching read-auto -> active If something has failed while the array was read-auto, then when we switch to 'active' we need to update the metadata. This will happen anyway but it is good to expedite it, and also to ensure any failed device has been released by the underlying device before we try to action the ioctl which caused us to switch to 'active' mode. Reported-by: Joe Lawrence Signed-off-by: NeilBrown --- drivers/md/md.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index f363135144f6..fcb878f88796 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -6532,7 +6532,17 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode, mddev->ro = 0; sysfs_notify_dirent_safe(mddev->sysfs_state); set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); - md_wakeup_thread(mddev->thread); + /* mddev_unlock will wake thread */ + /* If a device failed while we were read-only, we + * need to make sure the metadata is updated now. + */ + if (test_bit(MD_CHANGE_DEVS, &mddev->flags)) { + mddev_unlock(mddev); + wait_event(mddev->sb_wait, + !test_bit(MD_CHANGE_DEVS, &mddev->flags) && + !test_bit(MD_CHANGE_PENDING, &mddev->flags)); + mddev_lock(mddev); + } } else { err = -EROFS; goto abort_unlock; -- cgit v1.2.3 From 98891754ea9453de4db9111c91b20122ca330101 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2013 11:28:19 +0100 Subject: iwlwifi: don't map complete commands bidirectionally The reason we mapped them bidirectionally was that not doing so had caused IOMMU exceptions, due to the fact that the HW writes back into the command. Now that the first part of the command including the write-back part is always in the first buffer, we don't need to map the remaining buffer(s) bidi and can get rid of the special-casing for commands. This is a requisite patch for another one to fix DMA mapping. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/pcie/tx.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 8b625a7f5685..975492f0b8c8 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -367,8 +367,8 @@ static inline u8 iwl_pcie_tfd_get_num_tbs(struct iwl_tfd *tfd) } static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, - struct iwl_cmd_meta *meta, struct iwl_tfd *tfd, - enum dma_data_direction dma_dir) + struct iwl_cmd_meta *meta, + struct iwl_tfd *tfd) { int i; int num_tbs; @@ -392,7 +392,8 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), - iwl_pcie_tfd_tb_get_len(tfd, i), dma_dir); + iwl_pcie_tfd_tb_get_len(tfd, i), + DMA_TO_DEVICE); tfd->num_tbs = 0; } @@ -406,8 +407,7 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, * Does NOT advance any TFD circular buffer read/write indexes * Does NOT free the TFD itself (which is within circular buffer) */ -static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, - enum dma_data_direction dma_dir) +static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq) { struct iwl_tfd *tfd_tmp = txq->tfds; @@ -418,8 +418,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq, lockdep_assert_held(&txq->lock); /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ - iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr], - dma_dir); + iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]); /* free SKB */ if (txq->entries) { @@ -565,22 +564,13 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id) struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_txq *txq = &trans_pcie->txq[txq_id]; struct iwl_queue *q = &txq->q; - enum dma_data_direction dma_dir; if (!q->n_bd) return; - /* In the command queue, all the TBs are mapped as BIDI - * so unmap them as such. - */ - if (txq_id == trans_pcie->cmd_queue) - dma_dir = DMA_BIDIRECTIONAL; - else - dma_dir = DMA_TO_DEVICE; - spin_lock_bh(&txq->lock); while (q->write_ptr != q->read_ptr) { - iwl_pcie_txq_free_tfd(trans, txq, dma_dir); + iwl_pcie_txq_free_tfd(trans, txq); q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); } spin_unlock_bh(&txq->lock); @@ -962,7 +952,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn, iwl_pcie_txq_inval_byte_cnt_tbl(trans, txq); - iwl_pcie_txq_free_tfd(trans, txq, DMA_TO_DEVICE); + iwl_pcie_txq_free_tfd(trans, txq); } iwl_pcie_txq_progress(trans_pcie, txq); @@ -1340,11 +1330,10 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (cmd->dataflags[i] & IWL_HCMD_DFL_DUP) data = dup_buf; phys_addr = dma_map_single(trans->dev, (void *)data, - cmdlen[i], DMA_BIDIRECTIONAL); + cmdlen[i], DMA_TO_DEVICE); if (dma_mapping_error(trans->dev, phys_addr)) { iwl_pcie_tfd_unmap(trans, out_meta, - &txq->tfds[q->write_ptr], - DMA_BIDIRECTIONAL); + &txq->tfds[q->write_ptr]); idx = -ENOMEM; goto out; } @@ -1418,7 +1407,7 @@ void iwl_pcie_hcmd_complete(struct iwl_trans *trans, cmd = txq->entries[cmd_index].cmd; meta = &txq->entries[cmd_index].meta; - iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index], DMA_BIDIRECTIONAL); + iwl_pcie_tfd_unmap(trans, meta, &txq->tfds[index]); /* Input error checking is done when commands are added to queue. */ if (meta->flags & CMD_WANT_SKB) { -- cgit v1.2.3 From 1afbfb6041fb8f639e742620ad933c347e14ba2c Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Tue, 26 Feb 2013 11:32:26 +0100 Subject: iwlwifi: rename IWL_MAX_CMD_TFDS to IWL_MAX_CMD_TBS_PER_TFD The IWL_MAX_CMD_TFDS name for this constant is wrong, the constant really indicates how many TBs we can use in the driver for a single command TFD, rename the constant and also add a comment explaining it. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 12 ++++++++---- drivers/net/wireless/iwlwifi/pcie/tx.c | 12 ++++++------ 3 files changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index 10f01793d7a6..81aa91fab5aa 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -363,7 +363,7 @@ TRACE_EVENT(iwlwifi_dev_hcmd, __entry->flags = cmd->flags; memcpy(__get_dynamic_array(hcmd), hdr, sizeof(*hdr)); - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { if (!cmd->len[i]) continue; memcpy((u8 *)__get_dynamic_array(hcmd) + offset, diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 8c7bec6b9a0b..058947f213b2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -217,7 +217,11 @@ struct iwl_device_cmd { #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct iwl_device_cmd)) -#define IWL_MAX_CMD_TFDS 2 +/* + * number of transfer buffers (fragments) per transmit frame descriptor; + * this is just the driver's idea, the hardware supports 20 + */ +#define IWL_MAX_CMD_TBS_PER_TFD 2 /** * struct iwl_hcmd_dataflag - flag for each one of the chunks of the command @@ -254,15 +258,15 @@ enum iwl_hcmd_dataflag { * @id: id of the host command */ struct iwl_host_cmd { - const void *data[IWL_MAX_CMD_TFDS]; + const void *data[IWL_MAX_CMD_TBS_PER_TFD]; struct iwl_rx_packet *resp_pkt; unsigned long _rx_page_addr; u32 _rx_page_order; int handler_status; u32 flags; - u16 len[IWL_MAX_CMD_TFDS]; - u8 dataflags[IWL_MAX_CMD_TFDS]; + u16 len[IWL_MAX_CMD_TBS_PER_TFD]; + u8 dataflags[IWL_MAX_CMD_TBS_PER_TFD]; u8 id; }; diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index 975492f0b8c8..ff80a7e55f00 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -1146,16 +1146,16 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, bool had_nocopy = false; int i; u32 cmd_pos; - const u8 *cmddata[IWL_MAX_CMD_TFDS]; - u16 cmdlen[IWL_MAX_CMD_TFDS]; + const u8 *cmddata[IWL_MAX_CMD_TBS_PER_TFD]; + u16 cmdlen[IWL_MAX_CMD_TBS_PER_TFD]; copy_size = sizeof(out_cmd->hdr); cmd_size = sizeof(out_cmd->hdr); /* need one for the header if the first is NOCOPY */ - BUILD_BUG_ON(IWL_MAX_CMD_TFDS > IWL_NUM_OF_TBS - 1); + BUILD_BUG_ON(IWL_MAX_CMD_TBS_PER_TFD > IWL_NUM_OF_TBS - 1); - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { cmddata[i] = cmd->data[i]; cmdlen[i] = cmd->len[i]; @@ -1250,7 +1250,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, /* and copy the data that needs to be copied */ cmd_pos = offsetof(struct iwl_device_cmd, payload); copy_size = sizeof(out_cmd->hdr); - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { int copy = 0; if (!cmd->len) @@ -1319,7 +1319,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); /* map the remaining (adjusted) nocopy/dup fragments */ - for (i = 0; i < IWL_MAX_CMD_TFDS; i++) { + for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { const void *data = cmddata[i]; if (!cmdlen[i]) -- cgit v1.2.3 From aed7d9ac1836defe033b561f4306e39014ac56fd Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Wed, 20 Feb 2013 11:33:00 +0200 Subject: iwlwifi: disable 8K A-MSDU by default Supporting 8K A-MSDU means that we need to allocate order 1 pages for every Rx packet. Even when there is no traffic. This adds stress on the memory manager. The handling of compound pages is also less trivial for the memory manager and not using them will make the allocation code run faster although I didn't really measure. Eric also pointed out that having huge buffers with little data in them is not very nice towards the TCP stack since the truesize of the skb is huge. This doesn't allow TCP to have a big Rx window. See https://patchwork.kernel.org/patch/2167711/ for details. Note that very few vendors will actually send A-MSDU. Disable this feature by default. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/iwl-drv.c | 3 +-- drivers/net/wireless/iwlwifi/iwl-modparams.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c index 6f228bb2b844..fbfd2d137117 100644 --- a/drivers/net/wireless/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/iwlwifi/iwl-drv.c @@ -1102,7 +1102,6 @@ void iwl_drv_stop(struct iwl_drv *drv) /* shared module parameters */ struct iwl_mod_params iwlwifi_mod_params = { - .amsdu_size_8K = 1, .restart_fw = 1, .plcp_check = true, .bt_coex_active = true, @@ -1207,7 +1206,7 @@ MODULE_PARM_DESC(11n_disable, "disable 11n functionality, bitmap: 1: full, 2: agg TX, 4: agg RX"); 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"); +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"); diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h index e5e3a79eae2f..2c2a729092f5 100644 --- a/drivers/net/wireless/iwlwifi/iwl-modparams.h +++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h @@ -91,7 +91,7 @@ enum iwl_power_level { * @sw_crypto: using hardware encryption, default = 0 * @disable_11n: disable 11n capabilities, default = 0, * use IWL_DISABLE_HT_* constants - * @amsdu_size_8K: enable 8K amsdu size, default = 1 + * @amsdu_size_8K: enable 8K amsdu size, default = 0 * @restart_fw: restart firmware, default = 1 * @plcp_check: enable plcp health check, default = true * @wd_disable: enable stuck queue check, default = 0 -- cgit v1.2.3 From 38c0f334b359953f010e9b921e0b55278d3918f7 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 27 Feb 2013 13:18:50 +0100 Subject: iwlwifi: use coherent DMA memory for command header Recently in commit 8a964f44e01ad3bbc208c3e80d931ba91b9ea786 ("iwlwifi: always copy first 16 bytes of commands") we fixed the problem that the hardware writes back to the command and that could overwrite parts of the data that was still needed and would thus be corrupted. Investigating this problem more closely we found that this write-back isn't really ordered very well with respect to other DMA traffic. Therefore, it sometimes happened that the write-back occurred after unmapping the command again which is clearly an issue and could corrupt the next allocation that goes to that spot, or (better) cause IOMMU faults. To fix this, allocate coherent memory for the first 16 bytes of each command, containing the write-back part, and use it for all queues. All the dynamic DMA mappings only need to be TO_DEVICE then. This ensures that even when the write-back happens "too late" it can't hit memory that has been freed or a mapping that doesn't exist any more. Since now the actual command is no longer modified, we can also remove CMD_WANT_HCMD and get rid of the DMA sync that was necessary to update the scratch pointer. Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/dvm/sta.c | 2 +- drivers/net/wireless/iwlwifi/iwl-trans.h | 8 +- drivers/net/wireless/iwlwifi/pcie/internal.h | 34 +++-- drivers/net/wireless/iwlwifi/pcie/rx.c | 14 +- drivers/net/wireless/iwlwifi/pcie/tx.c | 221 +++++++++++++-------------- 5 files changed, 137 insertions(+), 142 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/dvm/sta.c b/drivers/net/wireless/iwlwifi/dvm/sta.c index 94ef33838bc6..b775769f8322 100644 --- a/drivers/net/wireless/iwlwifi/dvm/sta.c +++ b/drivers/net/wireless/iwlwifi/dvm/sta.c @@ -151,7 +151,7 @@ int iwl_send_add_sta(struct iwl_priv *priv, sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : ""); if (!(flags & CMD_ASYNC)) { - cmd.flags |= CMD_WANT_SKB | CMD_WANT_HCMD; + cmd.flags |= CMD_WANT_SKB; might_sleep(); } diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h index 058947f213b2..0cac2b7af78b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans.h +++ b/drivers/net/wireless/iwlwifi/iwl-trans.h @@ -186,19 +186,13 @@ struct iwl_rx_packet { * @CMD_ASYNC: Return right away and don't want for the response * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the * response. The caller needs to call iwl_free_resp when done. - * @CMD_WANT_HCMD: The caller needs to get the HCMD that was sent in the - * response handler. Chunks flagged by %IWL_HCMD_DFL_NOCOPY won't be - * copied. The pointer passed to the response handler is in the transport - * ownership and don't need to be freed by the op_mode. This also means - * that the pointer is invalidated after the op_mode's handler returns. * @CMD_ON_DEMAND: This command is sent by the test mode pipe. */ enum CMD_MODE { CMD_SYNC = 0, CMD_ASYNC = BIT(0), CMD_WANT_SKB = BIT(1), - CMD_WANT_HCMD = BIT(2), - CMD_ON_DEMAND = BIT(3), + CMD_ON_DEMAND = BIT(2), }; #define DEF_CMD_PAYLOAD_SIZE 320 diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h index 3d62e8055352..148843e7f34f 100644 --- a/drivers/net/wireless/iwlwifi/pcie/internal.h +++ b/drivers/net/wireless/iwlwifi/pcie/internal.h @@ -137,10 +137,6 @@ static inline int iwl_queue_dec_wrap(int index, int n_bd) struct iwl_cmd_meta { /* only for SYNC commands, iff the reply skb is wanted */ struct iwl_host_cmd *source; - - DEFINE_DMA_UNMAP_ADDR(mapping); - DEFINE_DMA_UNMAP_LEN(len); - u32 flags; }; @@ -185,25 +181,36 @@ struct iwl_queue { /* * The FH will write back to the first TB only, so we need * to copy some data into the buffer regardless of whether - * it should be mapped or not. This indicates how much to - * copy, even for HCMDs it must be big enough to fit the - * DRAM scratch from the TX cmd, at least 16 bytes. + * it should be mapped or not. This indicates how big the + * first TB must be to include the scratch buffer. Since + * the scratch is 4 bytes at offset 12, it's 16 now. If we + * make it bigger then allocations will be bigger and copy + * slower, so that's probably not useful. */ -#define IWL_HCMD_MIN_COPY_SIZE 16 +#define IWL_HCMD_SCRATCHBUF_SIZE 16 struct iwl_pcie_txq_entry { struct iwl_device_cmd *cmd; - struct iwl_device_cmd *copy_cmd; struct sk_buff *skb; /* buffer to free after command completes */ const void *free_buf; struct iwl_cmd_meta meta; }; +struct iwl_pcie_txq_scratch_buf { + struct iwl_cmd_header hdr; + u8 buf[8]; + __le32 scratch; +}; + /** * struct iwl_txq - Tx Queue for DMA * @q: generic Rx/Tx queue descriptor * @tfds: transmit frame descriptors (DMA memory) + * @scratchbufs: start of command headers, including scratch buffers, for + * the writeback -- this is DMA memory and an array holding one buffer + * for each command on the queue + * @scratchbufs_dma: DMA address for the scratchbufs start * @entries: transmit entries (driver state) * @lock: queue lock * @stuck_timer: timer that fires if queue gets stuck @@ -217,6 +224,8 @@ struct iwl_pcie_txq_entry { struct iwl_txq { struct iwl_queue q; struct iwl_tfd *tfds; + struct iwl_pcie_txq_scratch_buf *scratchbufs; + dma_addr_t scratchbufs_dma; struct iwl_pcie_txq_entry *entries; spinlock_t lock; struct timer_list stuck_timer; @@ -225,6 +234,13 @@ struct iwl_txq { u8 active; }; +static inline dma_addr_t +iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx) +{ + return txq->scratchbufs_dma + + sizeof(struct iwl_pcie_txq_scratch_buf) * idx; +} + /** * struct iwl_trans_pcie - PCIe transport specific data * @rxq: all the RX queue data diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c index b0ae06d2456f..567e67ad1f61 100644 --- a/drivers/net/wireless/iwlwifi/pcie/rx.c +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c @@ -637,22 +637,14 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans, index = SEQ_TO_INDEX(sequence); cmd_index = get_cmd_index(&txq->q, index); - if (reclaim) { - struct iwl_pcie_txq_entry *ent; - ent = &txq->entries[cmd_index]; - cmd = ent->copy_cmd; - WARN_ON_ONCE(!cmd && ent->meta.flags & CMD_WANT_HCMD); - } else { + if (reclaim) + cmd = txq->entries[cmd_index].cmd; + else cmd = NULL; - } err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); if (reclaim) { - /* The original command isn't needed any more */ - kfree(txq->entries[cmd_index].copy_cmd); - txq->entries[cmd_index].copy_cmd = NULL; - /* nor is the duplicated part of the command */ kfree(txq->entries[cmd_index].free_buf); txq->entries[cmd_index].free_buf = NULL; } diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index ff80a7e55f00..8595c16f74de 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c @@ -191,12 +191,9 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data) } for (i = q->read_ptr; i != q->write_ptr; - i = iwl_queue_inc_wrap(i, q->n_bd)) { - struct iwl_tx_cmd *tx_cmd = - (struct iwl_tx_cmd *)txq->entries[i].cmd->payload; + i = iwl_queue_inc_wrap(i, q->n_bd)) IWL_ERR(trans, "scratch %d = 0x%08x\n", i, - get_unaligned_le32(&tx_cmd->scratch)); - } + le32_to_cpu(txq->scratchbufs[i].scratch)); iwl_op_mode_nic_error(trans->op_mode); } @@ -382,14 +379,8 @@ static void iwl_pcie_tfd_unmap(struct iwl_trans *trans, return; } - /* Unmap tx_cmd */ - if (num_tbs) - dma_unmap_single(trans->dev, - dma_unmap_addr(meta, mapping), - dma_unmap_len(meta, len), - DMA_BIDIRECTIONAL); + /* first TB is never freed - it's the scratchbuf data */ - /* Unmap chunks, if any. */ for (i = 1; i < num_tbs; i++) dma_unmap_single(trans->dev, iwl_pcie_tfd_tb_get_addr(tfd, i), iwl_pcie_tfd_tb_get_len(tfd, i), @@ -478,6 +469,7 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, { struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); size_t tfd_sz = sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX; + size_t scratchbuf_sz; int i; if (WARN_ON(txq->entries || txq->tfds)) @@ -513,9 +505,25 @@ static int iwl_pcie_txq_alloc(struct iwl_trans *trans, IWL_ERR(trans, "dma_alloc_coherent(%zd) failed\n", tfd_sz); goto error; } + + BUILD_BUG_ON(IWL_HCMD_SCRATCHBUF_SIZE != sizeof(*txq->scratchbufs)); + BUILD_BUG_ON(offsetof(struct iwl_pcie_txq_scratch_buf, scratch) != + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch)); + + scratchbuf_sz = sizeof(*txq->scratchbufs) * slots_num; + + txq->scratchbufs = dma_alloc_coherent(trans->dev, scratchbuf_sz, + &txq->scratchbufs_dma, + GFP_KERNEL); + if (!txq->scratchbufs) + goto err_free_tfds; + txq->q.id = txq_id; return 0; +err_free_tfds: + dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->q.dma_addr); error: if (txq->entries && txq_id == trans_pcie->cmd_queue) for (i = 0; i < slots_num; i++) @@ -600,7 +608,6 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) if (txq_id == trans_pcie->cmd_queue) for (i = 0; i < txq->q.n_window; i++) { kfree(txq->entries[i].cmd); - kfree(txq->entries[i].copy_cmd); kfree(txq->entries[i].free_buf); } @@ -609,6 +616,10 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id) dma_free_coherent(dev, sizeof(struct iwl_tfd) * txq->q.n_bd, txq->tfds, txq->q.dma_addr); txq->q.dma_addr = 0; + + dma_free_coherent(dev, + sizeof(*txq->scratchbufs) * txq->q.n_window, + txq->scratchbufs, txq->scratchbufs_dma); } kfree(txq->entries); @@ -1142,7 +1153,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, void *dup_buf = NULL; dma_addr_t phys_addr; int idx; - u16 copy_size, cmd_size, dma_size; + u16 copy_size, cmd_size, scratch_size; bool had_nocopy = false; int i; u32 cmd_pos; @@ -1162,9 +1173,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (!cmd->len[i]) continue; - /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ - if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { - int copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ + if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { + int copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; if (copy > cmdlen[i]) copy = cmdlen[i]; @@ -1256,9 +1267,9 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, if (!cmd->len) continue; - /* need at least IWL_HCMD_MIN_COPY_SIZE copied */ - if (copy_size < IWL_HCMD_MIN_COPY_SIZE) { - copy = IWL_HCMD_MIN_COPY_SIZE - copy_size; + /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */ + if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) { + copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size; if (copy > cmd->len[i]) copy = cmd->len[i]; @@ -1276,48 +1287,36 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans, } } - WARN_ON_ONCE(txq->entries[idx].copy_cmd); - - /* - * since out_cmd will be the source address of the FH, it will write - * the retry count there. So when the user needs to receivce the HCMD - * that corresponds to the response in the response handler, it needs - * to set CMD_WANT_HCMD. - */ - if (cmd->flags & CMD_WANT_HCMD) { - txq->entries[idx].copy_cmd = - kmemdup(out_cmd, cmd_pos, GFP_ATOMIC); - if (unlikely(!txq->entries[idx].copy_cmd)) { - idx = -ENOMEM; - goto out; - } - } - IWL_DEBUG_HC(trans, "Sending command %s (#%x), seq: 0x%04X, %d bytes at %d[%d]:%d\n", get_cmd_string(trans_pcie, out_cmd->hdr.cmd), out_cmd->hdr.cmd, le16_to_cpu(out_cmd->hdr.sequence), cmd_size, q->write_ptr, idx, trans_pcie->cmd_queue); - /* - * If the entire command is smaller than IWL_HCMD_MIN_COPY_SIZE, we must - * still map at least that many bytes for the hardware to write back to. - * We have enough space, so that's not a problem. - */ - dma_size = max_t(u16, copy_size, IWL_HCMD_MIN_COPY_SIZE); + /* start the TFD with the scratchbuf */ + scratch_size = min_t(int, copy_size, IWL_HCMD_SCRATCHBUF_SIZE); + memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size); + iwl_pcie_txq_build_tfd(trans, txq, + iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr), + scratch_size, 1); + + /* map first command fragment, if any remains */ + if (copy_size > scratch_size) { + phys_addr = dma_map_single(trans->dev, + ((u8 *)&out_cmd->hdr) + scratch_size, + copy_size - scratch_size, + DMA_TO_DEVICE); + if (dma_mapping_error(trans->dev, phys_addr)) { + iwl_pcie_tfd_unmap(trans, out_meta, + &txq->tfds[q->write_ptr]); + idx = -ENOMEM; + goto out; + } - phys_addr = dma_map_single(trans->dev, &out_cmd->hdr, dma_size, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { - idx = -ENOMEM; - goto out; + iwl_pcie_txq_build_tfd(trans, txq, phys_addr, + copy_size - scratch_size, 0); } - dma_unmap_addr_set(out_meta, mapping, phys_addr); - dma_unmap_len_set(out_meta, len, dma_size); - - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, copy_size, 1); - /* map the remaining (adjusted) nocopy/dup fragments */ for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { const void *data = cmddata[i]; @@ -1586,10 +1585,9 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, struct iwl_cmd_meta *out_meta; struct iwl_txq *txq; struct iwl_queue *q; - dma_addr_t phys_addr = 0; - dma_addr_t txcmd_phys; - dma_addr_t scratch_phys; - u16 len, firstlen, secondlen; + dma_addr_t tb0_phys, tb1_phys, scratch_phys; + void *tb1_addr; + u16 len, tb1_len, tb2_len; u8 wait_write_ptr = 0; __le16 fc = hdr->frame_control; u8 hdr_len = ieee80211_hdrlen(fc); @@ -1627,85 +1625,80 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, cpu_to_le16((u16)(QUEUE_TO_SEQ(txq_id) | INDEX_TO_SEQ(q->write_ptr))); + tb0_phys = iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr); + scratch_phys = tb0_phys + sizeof(struct iwl_cmd_header) + + offsetof(struct iwl_tx_cmd, scratch); + + tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); + tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); + /* Set up first empty entry in queue's array of Tx/cmd buffers */ out_meta = &txq->entries[q->write_ptr].meta; /* - * Use the first empty entry in this queue's command buffer array - * to contain the Tx command and MAC header concatenated together - * (payload data will be in another buffer). - * Size of this varies, due to varying MAC header length. - * If end is not dword aligned, we'll have 2 extra bytes at the end - * of the MAC header (device reads on dword boundaries). - * We'll tell device about this padding later. + * The second TB (tb1) points to the remainder of the TX command + * and the 802.11 header - dword aligned size + * (This calculation modifies the TX command, so do it before the + * setup of the first TB) */ - len = sizeof(struct iwl_tx_cmd) + - sizeof(struct iwl_cmd_header) + hdr_len; - firstlen = (len + 3) & ~3; + len = sizeof(struct iwl_tx_cmd) + sizeof(struct iwl_cmd_header) + + hdr_len - IWL_HCMD_SCRATCHBUF_SIZE; + tb1_len = (len + 3) & ~3; /* Tell NIC about any 2-byte padding after MAC header */ - if (firstlen != len) + if (tb1_len != len) tx_cmd->tx_flags |= TX_CMD_FLG_MH_PAD_MSK; - /* Physical address of this Tx command's header (not MAC header!), - * within command buffer array. */ - txcmd_phys = dma_map_single(trans->dev, - &dev_cmd->hdr, firstlen, - DMA_BIDIRECTIONAL); - if (unlikely(dma_mapping_error(trans->dev, txcmd_phys))) - goto out_err; - dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, firstlen); + /* The first TB points to the scratchbuf data - min_copy bytes */ + memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr, + IWL_HCMD_SCRATCHBUF_SIZE); + iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, + IWL_HCMD_SCRATCHBUF_SIZE, 1); - if (!ieee80211_has_morefrags(fc)) { - txq->need_update = 1; - } else { - wait_write_ptr = 1; - txq->need_update = 0; - } + /* there must be data left over for TB1 or this code must be changed */ + BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE); + + /* map the data for TB1 */ + tb1_addr = ((u8 *)&dev_cmd->hdr) + IWL_HCMD_SCRATCHBUF_SIZE; + tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, tb1_phys))) + goto out_err; + iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0); - /* Set up TFD's 2nd entry to point directly to remainder of skb, - * if any (802.11 null frames have no payload). */ - secondlen = skb->len - hdr_len; - if (secondlen > 0) { - phys_addr = dma_map_single(trans->dev, skb->data + hdr_len, - secondlen, DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(trans->dev, phys_addr))) { - dma_unmap_single(trans->dev, - dma_unmap_addr(out_meta, mapping), - dma_unmap_len(out_meta, len), - DMA_BIDIRECTIONAL); + /* + * Set up TFD's third entry to point directly to remainder + * of skb, if any (802.11 null frames have no payload). + */ + tb2_len = skb->len - hdr_len; + if (tb2_len > 0) { + dma_addr_t tb2_phys = dma_map_single(trans->dev, + skb->data + hdr_len, + tb2_len, DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(trans->dev, tb2_phys))) { + iwl_pcie_tfd_unmap(trans, out_meta, + &txq->tfds[q->write_ptr]); goto out_err; } + iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0); } - /* Attach buffers to TFD */ - iwl_pcie_txq_build_tfd(trans, txq, txcmd_phys, firstlen, 1); - if (secondlen > 0) - iwl_pcie_txq_build_tfd(trans, txq, phys_addr, secondlen, 0); - - scratch_phys = txcmd_phys + sizeof(struct iwl_cmd_header) + - offsetof(struct iwl_tx_cmd, scratch); - - /* take back ownership of DMA buffer to enable update */ - dma_sync_single_for_cpu(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); - tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); - tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); - /* Set up entry for this TFD in Tx byte-count array */ iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); - dma_sync_single_for_device(trans->dev, txcmd_phys, firstlen, - DMA_BIDIRECTIONAL); - trace_iwlwifi_dev_tx(trans->dev, skb, &txq->tfds[txq->q.write_ptr], sizeof(struct iwl_tfd), - &dev_cmd->hdr, firstlen, - skb->data + hdr_len, secondlen); + &dev_cmd->hdr, IWL_HCMD_SCRATCHBUF_SIZE + tb1_len, + skb->data + hdr_len, tb2_len); trace_iwlwifi_dev_tx_data(trans->dev, skb, - skb->data + hdr_len, secondlen); + skb->data + hdr_len, tb2_len); + + if (!ieee80211_has_morefrags(fc)) { + txq->need_update = 1; + } else { + wait_write_ptr = 1; + txq->need_update = 0; + } /* start timer if queue currently empty */ if (txq->need_update && q->read_ptr == q->write_ptr && -- cgit v1.2.3 From faf1e7857a1b87cd8baf48c3e962142e21ad417c Mon Sep 17 00:00:00 2001 From: françois romieu Date: Wed, 27 Feb 2013 13:01:57 +0000 Subject: r8169: honor jumbo settings when chipset is requested to start. Some hardware start settings implicitely assume an usual 1500 bytes mtu that can't be guaranteed because changes of mtu may be requested both before and after the hardware is started. Reported-by: Tomi Orava Signed-off-by: Francois Romieu Cc: Hayes Wang Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 8900398ba103..28fb50a1e9c3 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -4765,8 +4765,10 @@ static void rtl_hw_start_8168bb(struct rtl8169_private *tp) RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); - rtl_tx_performance_tweak(pdev, - (0x5 << MAX_READ_REQUEST_SHIFT) | PCI_EXP_DEVCTL_NOSNOOP_EN); + if (tp->dev->mtu <= ETH_DATA_LEN) { + rtl_tx_performance_tweak(pdev, (0x5 << MAX_READ_REQUEST_SHIFT) | + PCI_EXP_DEVCTL_NOSNOOP_EN); + } } static void rtl_hw_start_8168bef(struct rtl8169_private *tp) @@ -4789,7 +4791,8 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_disable_clock_request(pdev); @@ -4822,7 +4825,8 @@ static void rtl_hw_start_8168cp_2(struct rtl8169_private *tp) RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } @@ -4841,7 +4845,8 @@ static void rtl_hw_start_8168cp_3(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, TxPacketMax); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } @@ -4901,7 +4906,8 @@ static void rtl_hw_start_8168d(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, TxPacketMax); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK); } @@ -4913,7 +4919,8 @@ static void rtl_hw_start_8168dp(struct rtl8169_private *tp) rtl_csi_access_enable_1(tp); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W8(MaxTxPacketSize, TxPacketMax); @@ -4972,7 +4979,8 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); RTL_W8(MaxTxPacketSize, TxPacketMax); @@ -4998,7 +5006,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); - rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); + if (tp->dev->mtu <= ETH_DATA_LEN) + rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); -- cgit v1.2.3 From 8ce7684533013d0a0dfbd627ed0430ecb0c82213 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 27 Feb 2013 13:06:44 +0000 Subject: bnx2x: Fix port identification for the 84834 Fix the "ethtool -p" for boards with BCM84834, by using LED4 of the PHY to toggle the link LED while keeping interrupt disabled to avoid NIG attentions, and at the end restore NIG to previous state. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 60 ++++++++++++++++++++++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 3 +- 2 files changed, 62 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 1663e0b6b5a0..4719ab1a31e3 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -10422,6 +10422,28 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x0); + if (phy->type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) { + /* Disable MI_INT interrupt before setting LED4 + * source to constant off. + */ + if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + params->port*4) & + NIG_MASK_MI_INT) { + params->link_flags |= + LINK_FLAGS_INT_DISABLED; + + bnx2x_bits_dis( + bp, + NIG_REG_MASK_INTERRUPT_PORT0 + + params->port*4, + NIG_MASK_MI_INT); + } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_SIGNAL_MASK, + 0x0); + } } break; case LED_MODE_ON: @@ -10468,6 +10490,28 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LED1_MASK, 0x20); + if (phy->type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) { + /* Disable MI_INT interrupt before setting LED4 + * source to constant on. + */ + if (REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + + params->port*4) & + NIG_MASK_MI_INT) { + params->link_flags |= + LINK_FLAGS_INT_DISABLED; + + bnx2x_bits_dis( + bp, + NIG_REG_MASK_INTERRUPT_PORT0 + + params->port*4, + NIG_MASK_MI_INT); + } + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_SIGNAL_MASK, + 0x20); + } } break; @@ -10532,6 +10576,22 @@ static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_LINK_SIGNAL, val); + if (phy->type == + PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84834) { + /* Restore LED4 source to external link, + * and re-enable interrupts. + */ + bnx2x_cl45_write(bp, phy, + MDIO_PMA_DEVAD, + MDIO_PMA_REG_8481_SIGNAL_MASK, + 0x40); + if (params->link_flags & + LINK_FLAGS_INT_DISABLED) { + bnx2x_link_int_enable(params); + params->link_flags &= + ~LINK_FLAGS_INT_DISABLED; + } + } } break; } diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index d25c7d79787a..be5c195d03dd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -307,7 +307,8 @@ struct link_params { struct bnx2x *bp; u16 req_fc_auto_adv; /* Should be set to TX / BOTH when req_flow_ctrl is set to AUTO */ - u16 rsrv1; + u16 link_flags; +#define LINK_FLAGS_INT_DISABLED (1<<0) u32 lfa_base; }; -- cgit v1.2.3 From be94bea753a4d5ac0982df07aaeaf0cb1f7554dd Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 27 Feb 2013 13:06:45 +0000 Subject: bnx2x: Fix KR2 link Fix KR2 link down problem after reboot when link speed is reconfigured via ethtool. Since 1G/10G support link speed were missing by default, 1G/10G link speed were not advertised. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c | 6 ++++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 ++ 2 files changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c index 9a674b14b403..edfa67adf2f9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c @@ -281,6 +281,8 @@ static int bnx2x_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) cmd->lp_advertising |= ADVERTISED_2500baseX_Full; if (status & LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE) cmd->lp_advertising |= ADVERTISED_10000baseT_Full; + if (status & LINK_STATUS_LINK_PARTNER_20GXFD_CAPABLE) + cmd->lp_advertising |= ADVERTISED_20000baseKR2_Full; } cmd->maxtxpkt = 0; @@ -463,6 +465,10 @@ static int bnx2x_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ADVERTISED_10000baseKR_Full)) bp->link_params.speed_cap_mask[cfg_idx] |= PORT_HW_CFG_SPEED_CAPABILITY_D0_10G; + + if (cmd->advertising & ADVERTISED_20000baseKR2_Full) + bp->link_params.speed_cap_mask[cfg_idx] |= + PORT_HW_CFG_SPEED_CAPABILITY_D0_20G; } } else { /* forced speed */ /* advertise the requested speed and duplex if supported */ diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 4719ab1a31e3..bf69c5306e46 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -11851,6 +11851,8 @@ static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port, phy->media_type = ETH_PHY_KR; phy->flags |= FLAGS_WC_DUAL_MODE; phy->supported &= (SUPPORTED_20000baseKR2_Full | + SUPPORTED_10000baseT_Full | + SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_FIBRE | SUPPORTED_Pause | -- cgit v1.2.3 From d521de04a73abb5e662c12eafa8c839aaaa6ae4f Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Wed, 27 Feb 2013 13:06:46 +0000 Subject: bnx2x: Fix KR2 work-around condition Fix condition typo for running KR2 work-around though it doesn't have real effect since the typo bits matched by chance. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 2 +- 1 file changed, 1 insertion(+), 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 bf69c5306e46..31c5787970db 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -13499,7 +13499,7 @@ void bnx2x_period_func(struct link_params *params, struct link_vars *vars) struct bnx2x_phy *phy = ¶ms->phy[INT_PHY]; bnx2x_set_aer_mmd(params, phy); if ((phy->supported & SUPPORTED_20000baseKR2_Full) && - (phy->speed_cap_mask & SPEED_20000)) + (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)) bnx2x_check_kr2_wa(params, vars, phy); bnx2x_check_over_curr(params, vars); if (vars->rx_tx_asic_rst) -- cgit v1.2.3 From b2a431915d19893f047e0dd149d0c1b9d2a0b960 Mon Sep 17 00:00:00 2001 From: Petr Malat Date: Thu, 28 Feb 2013 01:01:52 +0000 Subject: phy: Fix phy_device_free memory leak Fix memory leak in phy_device_free() for the case when phy_device* returned by phy_device_create() is not registered in the system. Bug description: phy_device_create() sets name of kobject using dev_set_name(), which allocates memory using kvasprintf(), but this memory isn't freed if the underlying device isn't registered properly, because kobject_cleanup() is not called in that case. This can happen (and actually is happening on our machines) if phy_device_register(), called by mdiobus_scan(), fails. Patch description: Embedded struct device is initialized in phy_device_create() and it counterpart phy_device_free() just drops one reference to the device, which leads to proper deinitialization including releasing the kobject name memory. Signed-off-by: Petr Malat Signed-off-by: David S. Miller --- drivers/net/phy/phy_device.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 9930f9999561..3657b4a29124 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -44,13 +44,13 @@ MODULE_LICENSE("GPL"); void phy_device_free(struct phy_device *phydev) { - kfree(phydev); + put_device(&phydev->dev); } EXPORT_SYMBOL(phy_device_free); static void phy_device_release(struct device *dev) { - phy_device_free(to_phy_device(dev)); + kfree(to_phy_device(dev)); } static struct phy_driver genphy_driver; @@ -201,6 +201,8 @@ struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id, there's no driver _already_ loaded. */ request_module(MDIO_MODULE_PREFIX MDIO_ID_FMT, MDIO_ID_ARGS(phy_id)); + device_initialize(&dev->dev); + return dev; } EXPORT_SYMBOL(phy_device_create); @@ -363,9 +365,9 @@ int phy_device_register(struct phy_device *phydev) /* Run all of the fixups for this PHY */ phy_scan_fixups(phydev); - err = device_register(&phydev->dev); + err = device_add(&phydev->dev); if (err) { - pr_err("phy %d failed to register\n", phydev->addr); + pr_err("PHY %d failed to add\n", phydev->addr); goto out; } -- cgit v1.2.3 From 02e711276d444343656c25b91b42996c62726712 Mon Sep 17 00:00:00 2001 From: Hauke Mehrtens Date: Thu, 28 Feb 2013 07:16:54 +0000 Subject: bgmac: omit the fcs Do not include the frame check sequence when adding the skb to netif_receive_skb(). This causes problems when this interface was bridged to a wifi ap and a big package should be forwarded from this Ethernet driver through a bride to the wifi client. Signed-off-by: Hauke Mehrtens Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bgmac.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index bf985c04524e..bce30e72dfde 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -301,12 +301,16 @@ static int bgmac_dma_rx_read(struct bgmac *bgmac, struct bgmac_dma_ring *ring, bgmac_err(bgmac, "Found poisoned packet at slot %d, DMA issue!\n", ring->start); } else { + /* Omit CRC. */ + len -= ETH_FCS_LEN; + new_skb = netdev_alloc_skb_ip_align(bgmac->net_dev, len); if (new_skb) { skb_put(new_skb, len); skb_copy_from_linear_data_offset(skb, BGMAC_RX_FRAME_OFFSET, new_skb->data, len); + skb_checksum_none_assert(skb); new_skb->protocol = eth_type_trans(new_skb, bgmac->net_dev); netif_receive_skb(new_skb); -- cgit v1.2.3 From 32fcafbcd1c9f6c7013016a22a5369b4acb93577 Mon Sep 17 00:00:00 2001 From: Vlastimil Kosar Date: Thu, 28 Feb 2013 08:45:22 +0000 Subject: net/phy: micrel: Disable asymmetric pause for KSZ9021 Phyter KSZ9021 has hardware bug. If asymmetric pause is enabled, then it is necessary to disconnect and then reconnect the ethernet cable to get the phyter working. The solution is to disable the asymmetric pause. Signed-off-by: Vlastimil Kosar Signed-off-by: David S. Miller --- drivers/net/phy/micrel.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 29934446436a..abf7b6153d00 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -257,8 +257,7 @@ static struct phy_driver ksphy_driver[] = { .phy_id = PHY_ID_KSZ9021, .phy_id_mask = 0x000ffffe, .name = "Micrel KSZ9021 Gigabit PHY", - .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause - | SUPPORTED_Asym_Pause), + .features = (PHY_GBIT_FEATURES | SUPPORTED_Pause), .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT, .config_init = kszphy_config_init, .config_aneg = genphy_config_aneg, -- cgit v1.2.3 From 4ceb73ae5a09416e040bce8bcfa7218dc5149ad8 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 24 Feb 2013 19:26:25 -0800 Subject: regulator: db8500-prcmu - remove incorrect __exit markup 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 Signed-off-by: Mark Brown --- drivers/regulator/db8500-prcmu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index 219d162b651e..a53c11a529d5 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c @@ -528,7 +528,7 @@ static int db8500_regulator_probe(struct platform_device *pdev) return 0; } -static int __exit db8500_regulator_remove(struct platform_device *pdev) +static int db8500_regulator_remove(struct platform_device *pdev) { int i; @@ -553,7 +553,7 @@ static struct platform_driver db8500_regulator_driver = { .owner = THIS_MODULE, }, .probe = db8500_regulator_probe, - .remove = __exit_p(db8500_regulator_remove), + .remove = db8500_regulator_remove, }; static int __init db8500_regulator_init(void) -- cgit v1.2.3 From 9345dfb8495aa17ce7c575e1a96e5ad64def0b3d Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Thu, 28 Feb 2013 18:44:54 -0600 Subject: regulator: core: fix documentation error in regulator_allow_bypass commit f59c8f9f (regulator: core: Support bypass mode) has a short documentation error around the regulator_allow_bypass parameter 'enable' which is documented as 'allow'. This generates kernel-doc warning as follows: ./scripts/kernel-doc drivers/regulator/core.c >/dev/null Warning(drivers/regulator/core.c:2841): No description found for parameter 'enable' Warning(drivers/regulator/core.c:2841): Excess function parameter 'allow' description in 'regulator_allow_bypass' Cc: Liam Girdwood Cc: Mark Brown Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Signed-off-by: Mark Brown --- drivers/regulator/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index da9782bd27d0..154bc8f0c1a0 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -2830,7 +2830,7 @@ EXPORT_SYMBOL_GPL(regulator_get_bypass_regmap); * regulator_allow_bypass - allow the regulator to go into bypass mode * * @regulator: Regulator to configure - * @allow: enable or disable bypass mode + * @enable: enable or disable bypass mode * * Allow the regulator to go into bypass mode if all other consumers * for the regulator also enable bypass mode and the machine -- cgit v1.2.3 From 283189d3be56aa6db6f192bb255df68493cd79ac Mon Sep 17 00:00:00 2001 From: Li Fei Date: Thu, 28 Feb 2013 15:37:11 +0800 Subject: regmap: irq: call pm_runtime_put 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: Mark Brown --- drivers/base/regmap/regmap-irq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/base/regmap/regmap-irq.c b/drivers/base/regmap/regmap-irq.c index 4706c63d0bc6..020ea2b9fd2f 100644 --- a/drivers/base/regmap/regmap-irq.c +++ b/drivers/base/regmap/regmap-irq.c @@ -184,6 +184,7 @@ static irqreturn_t regmap_irq_thread(int irq, void *d) if (ret < 0) { dev_err(map->dev, "IRQ thread failed to resume: %d\n", ret); + pm_runtime_put(map->dev); return IRQ_NONE; } } -- cgit v1.2.3 From a7dddf2757d09ba38683b359a721dc2efe85cd24 Mon Sep 17 00:00:00 2001 From: Graeme Gregory Date: Sat, 23 Feb 2013 16:35:40 +0000 Subject: regulator: palmas: fix number of SMPS voltages Number of voltages for SMPS regulators was off by one. Signed-off-by: Graeme Gregory Signed-off-by: Ian Lartey Acked-by: Laxman Dewangan Signed-off-by: Mark Brown --- drivers/regulator/palmas-regulator.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index cde13bb5a8fb..39cf14606784 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c @@ -4,6 +4,7 @@ * Copyright 2011-2012 Texas Instruments Inc. * * Author: Graeme Gregory + * Author: Ian Lartey * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -156,7 +157,7 @@ static const struct regs_info palmas_regs_info[] = { * * So they are basically (maxV-minV)/stepV */ -#define PALMAS_SMPS_NUM_VOLTAGES 116 +#define PALMAS_SMPS_NUM_VOLTAGES 117 #define PALMAS_SMPS10_NUM_VOLTAGES 2 #define PALMAS_LDO_NUM_VOLTAGES 50 -- cgit v1.2.3 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 v1.2.3 From 6949fbe5b2d7b73dfeddeb470a56385ca36b4827 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 16 Feb 2013 10:09:54 +0800 Subject: regulator: twl: Convert twl4030ldo_ops to get_voltage_sel This fixes an inconsistent behavior between list_voltage() and get_voltage() because current implementation of get_voltage() does not check the case IS_UNSUP() is true. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/twl-regulator.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 74508cc62d67..f705d25b437c 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c @@ -471,24 +471,23 @@ twl4030ldo_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) selector); } -static int twl4030ldo_get_voltage(struct regulator_dev *rdev) +static int twl4030ldo_get_voltage_sel(struct regulator_dev *rdev) { struct twlreg_info *info = rdev_get_drvdata(rdev); - int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, - VREG_VOLTAGE); + int vsel = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE); if (vsel < 0) return vsel; vsel &= info->table_len - 1; - return LDO_MV(info->table[vsel]) * 1000; + return vsel; } static struct regulator_ops twl4030ldo_ops = { .list_voltage = twl4030ldo_list_voltage, .set_voltage_sel = twl4030ldo_set_voltage_sel, - .get_voltage = twl4030ldo_get_voltage, + .get_voltage_sel = twl4030ldo_get_voltage_sel, .enable = twl4030reg_enable, .disable = twl4030reg_disable, -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 From fbe31057fafebdc2811a7101b8b4a0460f5417d1 Mon Sep 17 00:00:00 2001 From: Andrzej Hajda Date: Fri, 1 Mar 2013 12:24:05 +0100 Subject: regulator: fixed regulator_bulk_enable unwinding code Unwinding code disables all successfully enabled regulators. Error is logged for every failed regulator. Signed-off-by: Andrzej Hajda Signed-off-by: Kyungmin Park Signed-off-by: Mark Brown --- drivers/regulator/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index da9782bd27d0..4a7790c58257 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -3057,9 +3057,13 @@ int regulator_bulk_enable(int num_consumers, return 0; err: - pr_err("Failed to enable %s: %d\n", consumers[i].supply, ret); - while (--i >= 0) - regulator_disable(consumers[i].consumer); + for (i = 0; i < num_consumers; i++) { + if (consumers[i].ret < 0) + pr_err("Failed to enable %s: %d\n", consumers[i].supply, + consumers[i].ret); + else + regulator_disable(consumers[i].consumer); + } return ret; } -- cgit v1.2.3 From a72d9002f80bffd7e4c7d60e5a9caa0cddffe894 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 28 Feb 2013 10:34:23 +0800 Subject: xen/xen-blkback: preq.dev is used without initialized If call xen_vbd_translate failed, the preq.dev will be not initialized. Use blkif->vbd.pdevice instead (still better to print relative info). Note that before commit 01c681d4c70d64cb72142a2823f27c4146a02e63 (xen/blkback: Don't trust the handle from the frontend.) the value bogus, as it was the guest provided value from req->u.rw.handle rather than the actual device. Signed-off-by: Chen Gang Acked-by: Jan Beulich Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index de1f319f7bd7..6d1cc3df2ac6 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -904,7 +904,8 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, pr_debug(DRV_PFX "access denied: %s of [%llu,%llu] on dev=%04x\n", operation == READ ? "read" : "write", preq.sector_number, - preq.sector_number + preq.nr_sects, preq.dev); + preq.sector_number + preq.nr_sects, + blkif->vbd.pdevice); goto fail_response; } -- cgit v1.2.3 From cb29529ea0030e60ef1bbbf8399a43d397a51526 Mon Sep 17 00:00:00 2001 From: Tkhai Kirill Date: Sat, 23 Feb 2013 23:01:15 +0000 Subject: sunsu: Fix panic in case of nonexistent port at "console=ttySY" cmdline option If a machine has X (X < 4) sunsu ports and cmdline option "console=ttySY" is passed, where X < Y <= 4, than the following panic happens: Unable to handle kernel NULL pointer dereference TPC: RPC: I7: Call Trace: [0000000000453a38] register_console+0x378/0x3e0 [0000000000576fa0] uart_add_one_port+0x2e0/0x340 [000000000057af40] su_probe+0x160/0x2e0 [00000000005b8a4c] platform_drv_probe+0xc/0x20 [00000000005b6c2c] driver_probe_device+0x12c/0x220 [00000000005b6da8] __driver_attach+0x88/0xa0 [00000000005b4df4] bus_for_each_dev+0x54/0xa0 [00000000005b5a54] bus_add_driver+0x154/0x260 [00000000005b7190] driver_register+0x50/0x180 [00000000006d250c] sunsu_init+0x18c/0x1e0 [00000000006c2668] do_one_initcall+0xe8/0x160 [00000000006c282c] kernel_init_freeable+0x12c/0x1e0 [0000000000603764] kernel_init+0x4/0x100 [0000000000405f64] ret_from_syscall+0x1c/0x2c [0000000000000000] (null) 1)Fix the panic; 2)Increment registered port number every successful probe. Signed-off-by: Kirill Tkhai CC: David Miller Signed-off-by: David S. Miller --- drivers/tty/serial/sunsu.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/sunsu.c b/drivers/tty/serial/sunsu.c index e343d6670854..451687cb9685 100644 --- a/drivers/tty/serial/sunsu.c +++ b/drivers/tty/serial/sunsu.c @@ -968,6 +968,7 @@ static struct uart_ops sunsu_pops = { #define UART_NR 4 static struct uart_sunsu_port sunsu_ports[UART_NR]; +static int nr_inst; /* Number of already registered ports */ #ifdef CONFIG_SERIO @@ -1337,13 +1338,8 @@ static int __init sunsu_console_setup(struct console *co, char *options) printk("Console: ttyS%d (SU)\n", (sunsu_reg.minor - 64) + co->index); - /* - * Check whether an invalid uart number has been specified, and - * if so, search for the first available port that does have - * console support. - */ - if (co->index >= UART_NR) - co->index = 0; + if (co->index > nr_inst) + return -ENODEV; port = &sunsu_ports[co->index].port; /* @@ -1408,7 +1404,6 @@ static enum su_type su_get_type(struct device_node *dp) static int su_probe(struct platform_device *op) { - static int inst; struct device_node *dp = op->dev.of_node; struct uart_sunsu_port *up; struct resource *rp; @@ -1418,16 +1413,16 @@ static int su_probe(struct platform_device *op) type = su_get_type(dp); if (type == SU_PORT_PORT) { - if (inst >= UART_NR) + if (nr_inst >= UART_NR) return -EINVAL; - up = &sunsu_ports[inst]; + up = &sunsu_ports[nr_inst]; } else { up = kzalloc(sizeof(*up), GFP_KERNEL); if (!up) return -ENOMEM; } - up->port.line = inst; + up->port.line = nr_inst; spin_lock_init(&up->port.lock); @@ -1461,6 +1456,8 @@ static int su_probe(struct platform_device *op) } dev_set_drvdata(&op->dev, up); + nr_inst++; + return 0; } @@ -1488,7 +1485,7 @@ static int su_probe(struct platform_device *op) dev_set_drvdata(&op->dev, up); - inst++; + nr_inst++; return 0; -- cgit v1.2.3 From bcabdef12da49878789464ad7239e97d83ea5ef5 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 15 Feb 2013 14:46:14 +0900 Subject: gpiolib: check descriptors validity before use Some functions dereferenced their GPIO descriptor argument without checking its validity first, potentially leading to an oops when given an invalid argument. This patch also makes gpio_get_value() more resilient when given an invalid GPIO, returning 0 instead of silently crashing. Signed-off-by: Alexandre Courbot Cc: Ryan Mallon Signed-off-by: Grant Likely --- drivers/gpio/gpiolib.c | 112 ++++++++++++++++++++++++++++--------------------- 1 file changed, 65 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index fff9786cdc64..1a8a7a8f803f 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -174,7 +174,7 @@ static int gpio_ensure_requested(struct gpio_desc *desc) /* caller holds gpio_lock *OR* gpio is marked as requested */ static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc) { - return desc->chip; + return desc ? desc->chip : NULL; } struct gpio_chip *gpio_to_chip(unsigned gpio) @@ -654,6 +654,11 @@ static ssize_t export_store(struct class *class, goto done; desc = gpio_to_desc(gpio); + /* reject invalid GPIOs */ + if (!desc) { + pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); + return -EINVAL; + } /* No extra locking here; FLAG_SYSFS just signifies that the * request and export were done by on behalf of userspace, so @@ -690,12 +695,14 @@ static ssize_t unexport_store(struct class *class, if (status < 0) goto done; - status = -EINVAL; - desc = gpio_to_desc(gpio); /* reject bogus commands (gpio_unexport ignores them) */ - if (!desc) - goto done; + if (!desc) { + pr_warn("%s: invalid GPIO %ld\n", __func__, gpio); + return -EINVAL; + } + + status = -EINVAL; /* No extra locking here; FLAG_SYSFS just signifies that the * request and export were done by on behalf of userspace, so @@ -846,8 +853,10 @@ static int gpiod_export_link(struct device *dev, const char *name, { int status = -EINVAL; - if (!desc) - goto done; + if (!desc) { + pr_warn("%s: invalid GPIO\n", __func__); + return -EINVAL; + } mutex_lock(&sysfs_lock); @@ -865,7 +874,6 @@ static int gpiod_export_link(struct device *dev, const char *name, mutex_unlock(&sysfs_lock); -done: if (status) pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), status); @@ -896,8 +904,10 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value) struct device *dev = NULL; int status = -EINVAL; - if (!desc) - goto done; + if (!desc) { + pr_warn("%s: invalid GPIO\n", __func__); + return -EINVAL; + } mutex_lock(&sysfs_lock); @@ -914,7 +924,6 @@ static int gpiod_sysfs_set_active_low(struct gpio_desc *desc, int value) unlock: mutex_unlock(&sysfs_lock); -done: if (status) pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), status); @@ -940,8 +949,8 @@ static void gpiod_unexport(struct gpio_desc *desc) struct device *dev = NULL; if (!desc) { - status = -EINVAL; - goto done; + pr_warn("%s: invalid GPIO\n", __func__); + return; } mutex_lock(&sysfs_lock); @@ -962,7 +971,7 @@ static void gpiod_unexport(struct gpio_desc *desc) device_unregister(dev); put_device(dev); } -done: + if (status) pr_debug("%s: gpio%d status %d\n", __func__, desc_to_gpio(desc), status); @@ -1384,12 +1393,13 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) int status = -EPROBE_DEFER; unsigned long flags; - spin_lock_irqsave(&gpio_lock, flags); - if (!desc) { - status = -EINVAL; - goto done; + pr_warn("%s: invalid GPIO\n", __func__); + return -EINVAL; } + + spin_lock_irqsave(&gpio_lock, flags); + chip = desc->chip; if (chip == NULL) goto done; @@ -1432,8 +1442,7 @@ static int gpiod_request(struct gpio_desc *desc, const char *label) done: if (status) pr_debug("_gpio_request: gpio-%d (%s) status %d\n", - desc ? desc_to_gpio(desc) : -1, - label ? : "?", status); + desc_to_gpio(desc), label ? : "?", status); spin_unlock_irqrestore(&gpio_lock, flags); return status; } @@ -1616,10 +1625,13 @@ static int gpiod_direction_input(struct gpio_desc *desc) int status = -EINVAL; int offset; + if (!desc) { + pr_warn("%s: invalid GPIO\n", __func__); + return -EINVAL; + } + spin_lock_irqsave(&gpio_lock, flags); - if (!desc) - goto fail; chip = desc->chip; if (!chip || !chip->get || !chip->direction_input) goto fail; @@ -1655,13 +1667,9 @@ lose: return status; fail: spin_unlock_irqrestore(&gpio_lock, flags); - if (status) { - int gpio = -1; - if (desc) - gpio = desc_to_gpio(desc); - pr_debug("%s: gpio-%d status %d\n", - __func__, gpio, status); - } + if (status) + pr_debug("%s: gpio-%d status %d\n", __func__, + desc_to_gpio(desc), status); return status; } @@ -1678,6 +1686,11 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) int status = -EINVAL; int offset; + if (!desc) { + pr_warn("%s: invalid GPIO\n", __func__); + return -EINVAL; + } + /* Open drain pin should not be driven to 1 */ if (value && test_bit(FLAG_OPEN_DRAIN, &desc->flags)) return gpiod_direction_input(desc); @@ -1688,8 +1701,6 @@ static int gpiod_direction_output(struct gpio_desc *desc, int value) spin_lock_irqsave(&gpio_lock, flags); - if (!desc) - goto fail; chip = desc->chip; if (!chip || !chip->set || !chip->direction_output) goto fail; @@ -1725,13 +1736,9 @@ lose: return status; fail: spin_unlock_irqrestore(&gpio_lock, flags); - if (status) { - int gpio = -1; - if (desc) - gpio = desc_to_gpio(desc); - pr_debug("%s: gpio-%d status %d\n", - __func__, gpio, status); - } + if (status) + pr_debug("%s: gpio-%d status %d\n", __func__, + desc_to_gpio(desc), status); return status; } @@ -1753,10 +1760,13 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) int status = -EINVAL; int offset; + if (!desc) { + pr_warn("%s: invalid GPIO\n", __func__); + return -EINVAL; + } + spin_lock_irqsave(&gpio_lock, flags); - if (!desc) - goto fail; chip = desc->chip; if (!chip || !chip->set || !chip->set_debounce) goto fail; @@ -1776,13 +1786,9 @@ static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce) fail: spin_unlock_irqrestore(&gpio_lock, flags); - if (status) { - int gpio = -1; - if (desc) - gpio = desc_to_gpio(desc); - pr_debug("%s: gpio-%d status %d\n", - __func__, gpio, status); - } + if (status) + pr_debug("%s: gpio-%d status %d\n", __func__, + desc_to_gpio(desc), status); return status; } @@ -1830,6 +1836,8 @@ static int gpiod_get_value(struct gpio_desc *desc) int value; int offset; + if (!desc) + return 0; chip = desc->chip; offset = gpio_chip_hwgpio(desc); /* Should be using gpio_get_value_cansleep() */ @@ -1912,6 +1920,8 @@ static void gpiod_set_value(struct gpio_desc *desc, int value) { struct gpio_chip *chip; + if (!desc) + return; chip = desc->chip; /* Should be using gpio_set_value_cansleep() */ WARN_ON(chip->can_sleep); @@ -1940,6 +1950,8 @@ EXPORT_SYMBOL_GPL(__gpio_set_value); */ static int gpiod_cansleep(struct gpio_desc *desc) { + if (!desc) + return 0; /* only call this on GPIOs that are valid! */ return desc->chip->can_sleep; } @@ -1964,6 +1976,8 @@ static int gpiod_to_irq(struct gpio_desc *desc) struct gpio_chip *chip; int offset; + if (!desc) + return -EINVAL; chip = desc->chip; offset = gpio_chip_hwgpio(desc); return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO; @@ -1987,6 +2001,8 @@ static int gpiod_get_value_cansleep(struct gpio_desc *desc) int offset; might_sleep_if(extra_checks); + if (!desc) + return 0; chip = desc->chip; offset = gpio_chip_hwgpio(desc); value = chip->get ? chip->get(chip, offset) : 0; @@ -2005,6 +2021,8 @@ static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value) struct gpio_chip *chip; might_sleep_if(extra_checks); + if (!desc) + return; chip = desc->chip; trace_gpio_value(desc_to_gpio(desc), 0, value); if (test_bit(FLAG_OPEN_DRAIN, &desc->flags)) -- cgit v1.2.3 From def634338d3ffb32fbe9b0a2d70cc24ef909cd4f Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 15 Feb 2013 14:46:15 +0900 Subject: gpiolib: use const parameters when possible Constify descriptor parameter of gpiod_* functions for those that should obviously not modify it. This includes value or direction get, cansleep, and IRQ number query. Signed-off-by: Alexandre Courbot Signed-off-by: Grant Likely --- drivers/gpio/gpiolib.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 1a8a7a8f803f..a33bfc23e9f5 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -88,13 +88,14 @@ static int gpiod_request(struct gpio_desc *desc, const char *label); static void gpiod_free(struct gpio_desc *desc); static int gpiod_direction_input(struct gpio_desc *desc); static int gpiod_direction_output(struct gpio_desc *desc, int value); +static int gpiod_get_direction(const struct gpio_desc *desc); static int gpiod_set_debounce(struct gpio_desc *desc, unsigned debounce); -static int gpiod_get_value_cansleep(struct gpio_desc *desc); +static int gpiod_get_value_cansleep(const struct gpio_desc *desc); static void gpiod_set_value_cansleep(struct gpio_desc *desc, int value); -static int gpiod_get_value(struct gpio_desc *desc); +static int gpiod_get_value(const struct gpio_desc *desc); static void gpiod_set_value(struct gpio_desc *desc, int value); -static int gpiod_cansleep(struct gpio_desc *desc); -static int gpiod_to_irq(struct gpio_desc *desc); +static int gpiod_cansleep(const struct gpio_desc *desc); +static int gpiod_to_irq(const struct gpio_desc *desc); static int gpiod_export(struct gpio_desc *desc, bool direction_may_change); static int gpiod_export_link(struct device *dev, const char *name, struct gpio_desc *desc); @@ -172,7 +173,7 @@ static int gpio_ensure_requested(struct gpio_desc *desc) } /* caller holds gpio_lock *OR* gpio is marked as requested */ -static struct gpio_chip *gpiod_to_chip(struct gpio_desc *desc) +static struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) { return desc ? desc->chip : NULL; } @@ -207,7 +208,7 @@ static int gpiochip_find_base(int ngpio) } /* caller ensures gpio is valid and requested, chip->get_direction may sleep */ -static int gpiod_get_direction(struct gpio_desc *desc) +static int gpiod_get_direction(const struct gpio_desc *desc) { struct gpio_chip *chip; unsigned offset; @@ -223,11 +224,13 @@ static int gpiod_get_direction(struct gpio_desc *desc) if (status > 0) { /* GPIOF_DIR_IN, or other positive */ status = 1; - clear_bit(FLAG_IS_OUT, &desc->flags); + /* FLAG_IS_OUT is just a cache of the result of get_direction(), + * so it does not affect constness per se */ + clear_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags); } if (status == 0) { /* GPIOF_DIR_OUT */ - set_bit(FLAG_IS_OUT, &desc->flags); + set_bit(FLAG_IS_OUT, &((struct gpio_desc *)desc)->flags); } return status; } @@ -263,7 +266,7 @@ static DEFINE_MUTEX(sysfs_lock); static ssize_t gpio_direction_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct gpio_desc *desc = dev_get_drvdata(dev); + const struct gpio_desc *desc = dev_get_drvdata(dev); ssize_t status; mutex_lock(&sysfs_lock); @@ -1830,7 +1833,7 @@ EXPORT_SYMBOL_GPL(gpio_set_debounce); * It returns the zero or nonzero value provided by the associated * gpio_chip.get() method; or zero if no such method is provided. */ -static int gpiod_get_value(struct gpio_desc *desc) +static int gpiod_get_value(const struct gpio_desc *desc) { struct gpio_chip *chip; int value; @@ -1948,7 +1951,7 @@ EXPORT_SYMBOL_GPL(__gpio_set_value); * This is used directly or indirectly to implement gpio_cansleep(). It * returns nonzero if access reading or writing the GPIO value can sleep. */ -static int gpiod_cansleep(struct gpio_desc *desc) +static int gpiod_cansleep(const struct gpio_desc *desc) { if (!desc) return 0; @@ -1971,7 +1974,7 @@ EXPORT_SYMBOL_GPL(__gpio_cansleep); * It returns the number of the IRQ signaled by this (input) GPIO, * or a negative errno. */ -static int gpiod_to_irq(struct gpio_desc *desc) +static int gpiod_to_irq(const struct gpio_desc *desc) { struct gpio_chip *chip; int offset; @@ -1994,7 +1997,7 @@ EXPORT_SYMBOL_GPL(__gpio_to_irq); * Common examples include ones connected to I2C or SPI chips. */ -static int gpiod_get_value_cansleep(struct gpio_desc *desc) +static int gpiod_get_value_cansleep(const struct gpio_desc *desc) { struct gpio_chip *chip; int value; -- cgit v1.2.3 From 24d7628fe8b10bb3770a11ddf71719613832a298 Mon Sep 17 00:00:00 2001 From: Alexandre Courbot Date: Fri, 15 Feb 2013 14:46:16 +0900 Subject: gpiolib: move comment to right function This comment applies to gpio_to_chip(), not gpiod_to_chip(). Signed-off-by: Alexandre Courbot Signed-off-by: Grant Likely --- drivers/gpio/gpiolib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index a33bfc23e9f5..c2534d62911c 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c @@ -172,12 +172,12 @@ static int gpio_ensure_requested(struct gpio_desc *desc) return 0; } -/* caller holds gpio_lock *OR* gpio is marked as requested */ static struct gpio_chip *gpiod_to_chip(const struct gpio_desc *desc) { return desc ? desc->chip : NULL; } +/* caller holds gpio_lock *OR* gpio is marked as requested */ struct gpio_chip *gpio_to_chip(unsigned gpio) { return gpiod_to_chip(gpio_to_desc(gpio)); -- cgit v1.2.3 From e97f9b5277afeabb54892ebc6f68500098467ba1 Mon Sep 17 00:00:00 2001 From: Mika Westerberg Date: Wed, 27 Feb 2013 17:25:15 +0200 Subject: gpio/gpio-ich: fix ichx_gpio_check_available() return what callers expect ichx_gpio_check_available() returns either 0 or -ENXIO depending on whether the given GPIO is available or not. However, callers of this function treat the return value as boolean: ... if (!ichx_gpio_check_available(gpio, nr)) return -ENXIO; which erroneusly fails when the GPIO is available and not vice versa. Fix this by making the function return boolean as expected by the callers. Signed-off-by: Mika Westerberg Signed-off-by: Grant Likely --- drivers/gpio/gpio-ich.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c index 6f2306db8591..f9dbd503fc40 100644 --- a/drivers/gpio/gpio-ich.c +++ b/drivers/gpio/gpio-ich.c @@ -128,9 +128,9 @@ static int ichx_read_bit(int reg, unsigned nr) return data & (1 << bit) ? 1 : 0; } -static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) +static bool ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr) { - return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO; + return ichx_priv.use_gpio & (1 << (nr / 32)); } static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr) -- cgit v1.2.3 From a26302628ad164980493ab7768a05a7f3a8d8842 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 1 Mar 2013 13:07:00 +0000 Subject: iio:ad5064: Fix address of the second channel for ad5065/ad5045/ad5025 The ad5065, ad5045, ad5025 use address '3' for the second channel, so they need their own channel spec. Note that ad5064_sync_powerdown_mode() also needs to be slightly updated since it was relying on the fact that chan->address always equaled chan->channel. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5064.c | 49 ++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 2fe1d4edcb2f..7b777083cb48 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -27,7 +27,6 @@ #define AD5064_ADDR(x) ((x) << 20) #define AD5064_CMD(x) ((x) << 24) -#define AD5064_ADDR_DAC(chan) (chan) #define AD5064_ADDR_ALL_DAC 0xF #define AD5064_CMD_WRITE_INPUT_N 0x0 @@ -131,15 +130,15 @@ static int ad5064_write(struct ad5064_state *st, unsigned int cmd, } static int ad5064_sync_powerdown_mode(struct ad5064_state *st, - unsigned int channel) + const struct iio_chan_spec *chan) { unsigned int val; int ret; - val = (0x1 << channel); + val = (0x1 << chan->address); - if (st->pwr_down[channel]) - val |= st->pwr_down_mode[channel] << 8; + if (st->pwr_down[chan->channel]) + val |= st->pwr_down_mode[chan->channel] << 8; ret = ad5064_write(st, AD5064_CMD_POWERDOWN_DAC, 0, val, 0); @@ -169,7 +168,7 @@ static int ad5064_set_powerdown_mode(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->pwr_down_mode[chan->channel] = mode + 1; - ret = ad5064_sync_powerdown_mode(st, chan->channel); + ret = ad5064_sync_powerdown_mode(st, chan); mutex_unlock(&indio_dev->mlock); return ret; @@ -205,7 +204,7 @@ static ssize_t ad5064_write_dac_powerdown(struct iio_dev *indio_dev, mutex_lock(&indio_dev->mlock); st->pwr_down[chan->channel] = pwr_down; - ret = ad5064_sync_powerdown_mode(st, chan->channel); + ret = ad5064_sync_powerdown_mode(st, chan); mutex_unlock(&indio_dev->mlock); return ret ? ret : len; } @@ -292,34 +291,44 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = { { }, }; -#define AD5064_CHANNEL(chan, bits) { \ +#define AD5064_CHANNEL(chan, addr, bits) { \ .type = IIO_VOLTAGE, \ .indexed = 1, \ .output = 1, \ .channel = (chan), \ .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ - .address = AD5064_ADDR_DAC(chan), \ + .address = addr, \ .scan_type = IIO_ST('u', (bits), 16, 20 - (bits)), \ .ext_info = ad5064_ext_info, \ } #define DECLARE_AD5064_CHANNELS(name, bits) \ const struct iio_chan_spec name[] = { \ - AD5064_CHANNEL(0, bits), \ - AD5064_CHANNEL(1, bits), \ - AD5064_CHANNEL(2, bits), \ - AD5064_CHANNEL(3, bits), \ - AD5064_CHANNEL(4, bits), \ - AD5064_CHANNEL(5, bits), \ - AD5064_CHANNEL(6, bits), \ - AD5064_CHANNEL(7, bits), \ + AD5064_CHANNEL(0, 0, bits), \ + AD5064_CHANNEL(1, 1, bits), \ + AD5064_CHANNEL(2, 2, bits), \ + AD5064_CHANNEL(3, 3, bits), \ + AD5064_CHANNEL(4, 4, bits), \ + AD5064_CHANNEL(5, 5, bits), \ + AD5064_CHANNEL(6, 6, bits), \ + AD5064_CHANNEL(7, 7, bits), \ +} + +#define DECLARE_AD5065_CHANNELS(name, bits) \ +const struct iio_chan_spec name[] = { \ + AD5064_CHANNEL(0, 0, bits), \ + AD5064_CHANNEL(1, 3, bits), \ } static DECLARE_AD5064_CHANNELS(ad5024_channels, 12); static DECLARE_AD5064_CHANNELS(ad5044_channels, 14); static DECLARE_AD5064_CHANNELS(ad5064_channels, 16); +static DECLARE_AD5065_CHANNELS(ad5025_channels, 12); +static DECLARE_AD5065_CHANNELS(ad5045_channels, 14); +static DECLARE_AD5065_CHANNELS(ad5065_channels, 16); + static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { [ID_AD5024] = { .shared_vref = false, @@ -328,7 +337,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { }, [ID_AD5025] = { .shared_vref = false, - .channels = ad5024_channels, + .channels = ad5025_channels, .num_channels = 2, }, [ID_AD5044] = { @@ -338,7 +347,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { }, [ID_AD5045] = { .shared_vref = false, - .channels = ad5044_channels, + .channels = ad5045_channels, .num_channels = 2, }, [ID_AD5064] = { @@ -353,7 +362,7 @@ static const struct ad5064_chip_info ad5064_chip_info_tbl[] = { }, [ID_AD5065] = { .shared_vref = false, - .channels = ad5064_channels, + .channels = ad5065_channels, .num_channels = 2, }, [ID_AD5628_1] = { -- cgit v1.2.3 From c5ef717a774b326a6708e2e14ddf9957b619d5c4 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 1 Mar 2013 13:07:00 +0000 Subject: iio:ad5064: Fix off by one in DAC value range check The DAC value range check allows values one larger than the maximum value, which effectively results in setting the DAC value to 0. This patch fixes the issue. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5064.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index 7b777083cb48..f724a54bf334 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -257,7 +257,7 @@ static int ad5064_write_raw(struct iio_dev *indio_dev, switch (mask) { case IIO_CHAN_INFO_RAW: - if (val > (1 << chan->scan_type.realbits) || val < 0) + if (val >= (1 << chan->scan_type.realbits) || val < 0) return -EINVAL; mutex_lock(&indio_dev->mlock); -- cgit v1.2.3 From f77ae9d8fd4b8ed984f33e996c62f2dfd9f73b37 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 1 Mar 2013 13:07:00 +0000 Subject: iio:ad5064: Initialize register cache correctly Initialize the register cache to the proper mid-scale value based on the resolution of the device. Signed-off-by: Lars-Peter Clausen Signed-off-by: Jonathan Cameron --- drivers/iio/dac/ad5064.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/dac/ad5064.c b/drivers/iio/dac/ad5064.c index f724a54bf334..74f2d52795f6 100644 --- a/drivers/iio/dac/ad5064.c +++ b/drivers/iio/dac/ad5064.c @@ -438,6 +438,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, { struct iio_dev *indio_dev; struct ad5064_state *st; + unsigned int midscale; unsigned int i; int ret; @@ -474,11 +475,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, goto error_free_reg; } - for (i = 0; i < st->chip_info->num_channels; ++i) { - st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K; - st->dac_cache[i] = 0x8000; - } - indio_dev->dev.parent = dev; indio_dev->name = name; indio_dev->info = &ad5064_info; @@ -486,6 +482,13 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type, indio_dev->channels = st->chip_info->channels; indio_dev->num_channels = st->chip_info->num_channels; + midscale = (1 << indio_dev->channels[0].scan_type.realbits) / 2; + + for (i = 0; i < st->chip_info->num_channels; ++i) { + st->pwr_down_mode[i] = AD5064_LDAC_PWRDN_1K; + st->dac_cache[i] = midscale; + } + ret = iio_device_register(indio_dev); if (ret) goto error_disable_reg; -- cgit v1.2.3 From da0d4ef27ca1407e64b2ac9e75d2ca60bb83b618 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Fri, 1 Mar 2013 15:21:00 +0000 Subject: iio/imu: inv_mpu6050 depends on IIO_BUFFER MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix: drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c: In function ‘inv_mpu6050_read_fifo’: drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c:176:3: error: implicit declaration of function ‘iio_push_to_buffers’ [-Werror=implicit-function-declaration] Signed-off-by: Guenter Roeck Signed-off-by: Jonathan Cameron --- drivers/iio/imu/inv_mpu6050/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iio/imu/inv_mpu6050/Kconfig b/drivers/iio/imu/inv_mpu6050/Kconfig index b5cfa3a354cf..361b2328453d 100644 --- a/drivers/iio/imu/inv_mpu6050/Kconfig +++ b/drivers/iio/imu/inv_mpu6050/Kconfig @@ -5,6 +5,7 @@ config INV_MPU6050_IIO tristate "Invensense MPU6050 devices" depends on I2C && SYSFS + select IIO_BUFFER select IIO_TRIGGERED_BUFFER help This driver supports the Invensense MPU6050 devices. -- cgit v1.2.3 From e2ca90c276e1fc410d7cd3c1a4eee245ec902a20 Mon Sep 17 00:00:00 2001 From: Freddy Xin Date: Sat, 2 Mar 2013 00:41:11 +0000 Subject: ax88179_178a: ASIX AX88179_178A USB 3.0/2.0 to gigabit ethernet adapter driver This is a resubmission. Added kfree() in ax88179_get_eeprom to prevent memory leakage. Modified "__le16 rxctl" to "u16 rxctl" in "struct ax88179_data" and removed pointless casts. Removed asix_init and asix_exit functions and added "module_usb_driver(ax88179_178a_driver)". Fixed endianness issue on big endian systems and verified this driver on iBook G4. Removed steps that change net->features in ax88179_set_features function. Added "const" to ethtool_ops structure and fixed the coding style of AX88179_BULKIN_SIZE array. Fixed the issue that the default MTU is not 1500. Added ax88179_change_mtu function and enabled the hardware jumbo frame function to support an MTU higher than 1500. Fixed indentation and empty line coding style errors. The _nopm version usb functions were added to access register in suspend and resume functions. Serveral variables allocted dynamically were removed and replaced by stack variables. ax88179_get_eeprom were modified from asix_get_eeprom in asix_common. This patch adds a driver for ASIX's AX88179 family of USB 3.0/2.0 to gigabit ethernet adapters. It's based on the AX88xxx driver but the usb commands used to access registers for AX88179 are completely different. This driver had been verified on x86 system with AX88179/AX88178A and Sitcomm LN-032 USB dongles. Signed-off-by: Freddy Xin Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 18 + drivers/net/usb/Makefile | 1 + drivers/net/usb/ax88179_178a.c | 1448 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1467 insertions(+) create mode 100644 drivers/net/usb/ax88179_178a.c (limited to 'drivers') diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index da92ed3797aa..3b6e9b83342d 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -156,6 +156,24 @@ config USB_NET_AX8817X This driver creates an interface named "ethX", where X depends on what other networking devices you have in use. +config USB_NET_AX88179_178A + tristate "ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet" + depends on USB_USBNET + select CRC32 + select PHYLIB + default y + help + This option adds support for ASIX AX88179 based USB 3.0/2.0 + to Gigabit Ethernet adapters. + + This driver should work with at least the following devices: + * ASIX AX88179 + * ASIX AX88178A + * Sitcomm LN-032 + + This driver creates an interface named "ethX", where X depends on + what other networking devices you have in use. + config USB_NET_CDCETHER tristate "CDC Ethernet support (smart devices such as cable modems)" depends on USB_USBNET diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 478691326f37..119b06c9aa16 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_USB_RTL8150) += rtl8150.o obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o +obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o diff --git a/drivers/net/usb/ax88179_178a.c b/drivers/net/usb/ax88179_178a.c new file mode 100644 index 000000000000..71c27d8d214f --- /dev/null +++ b/drivers/net/usb/ax88179_178a.c @@ -0,0 +1,1448 @@ +/* + * ASIX AX88179/178A USB 3.0/2.0 to Gigabit Ethernet Devices + * + * Copyright (C) 2011-2013 ASIX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the 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 + +#define AX88179_PHY_ID 0x03 +#define AX_EEPROM_LEN 0x100 +#define AX88179_EEPROM_MAGIC 0x17900b95 +#define AX_MCAST_FLTSIZE 8 +#define AX_MAX_MCAST 64 +#define AX_INT_PPLS_LINK ((u32)BIT(16)) +#define AX_RXHDR_L4_TYPE_MASK 0x1c +#define AX_RXHDR_L4_TYPE_UDP 4 +#define AX_RXHDR_L4_TYPE_TCP 16 +#define AX_RXHDR_L3CSUM_ERR 2 +#define AX_RXHDR_L4CSUM_ERR 1 +#define AX_RXHDR_CRC_ERR ((u32)BIT(31)) +#define AX_RXHDR_DROP_ERR ((u32)BIT(30)) +#define AX_ACCESS_MAC 0x01 +#define AX_ACCESS_PHY 0x02 +#define AX_ACCESS_EEPROM 0x04 +#define AX_ACCESS_EFUS 0x05 +#define AX_PAUSE_WATERLVL_HIGH 0x54 +#define AX_PAUSE_WATERLVL_LOW 0x55 + +#define PHYSICAL_LINK_STATUS 0x02 + #define AX_USB_SS 0x04 + #define AX_USB_HS 0x02 + +#define GENERAL_STATUS 0x03 +/* Check AX88179 version. UA1:Bit2 = 0, UA2:Bit2 = 1 */ + #define AX_SECLD 0x04 + +#define AX_SROM_ADDR 0x07 +#define AX_SROM_CMD 0x0a + #define EEP_RD 0x04 + #define EEP_BUSY 0x10 + +#define AX_SROM_DATA_LOW 0x08 +#define AX_SROM_DATA_HIGH 0x09 + +#define AX_RX_CTL 0x0b + #define AX_RX_CTL_DROPCRCERR 0x0100 + #define AX_RX_CTL_IPE 0x0200 + #define AX_RX_CTL_START 0x0080 + #define AX_RX_CTL_AP 0x0020 + #define AX_RX_CTL_AM 0x0010 + #define AX_RX_CTL_AB 0x0008 + #define AX_RX_CTL_AMALL 0x0002 + #define AX_RX_CTL_PRO 0x0001 + #define AX_RX_CTL_STOP 0x0000 + +#define AX_NODE_ID 0x10 +#define AX_MULFLTARY 0x16 + +#define AX_MEDIUM_STATUS_MODE 0x22 + #define AX_MEDIUM_GIGAMODE 0x01 + #define AX_MEDIUM_FULL_DUPLEX 0x02 + #define AX_MEDIUM_ALWAYS_ONE 0x04 + #define AX_MEDIUM_EN_125MHZ 0x08 + #define AX_MEDIUM_RXFLOW_CTRLEN 0x10 + #define AX_MEDIUM_TXFLOW_CTRLEN 0x20 + #define AX_MEDIUM_RECEIVE_EN 0x100 + #define AX_MEDIUM_PS 0x200 + #define AX_MEDIUM_JUMBO_EN 0x8040 + +#define AX_MONITOR_MOD 0x24 + #define AX_MONITOR_MODE_RWLC 0x02 + #define AX_MONITOR_MODE_RWMP 0x04 + #define AX_MONITOR_MODE_PMEPOL 0x20 + #define AX_MONITOR_MODE_PMETYPE 0x40 + +#define AX_GPIO_CTRL 0x25 + #define AX_GPIO_CTRL_GPIO3EN 0x80 + #define AX_GPIO_CTRL_GPIO2EN 0x40 + #define AX_GPIO_CTRL_GPIO1EN 0x20 + +#define AX_PHYPWR_RSTCTL 0x26 + #define AX_PHYPWR_RSTCTL_BZ 0x0010 + #define AX_PHYPWR_RSTCTL_IPRL 0x0020 + #define AX_PHYPWR_RSTCTL_AT 0x1000 + +#define AX_RX_BULKIN_QCTRL 0x2e +#define AX_CLK_SELECT 0x33 + #define AX_CLK_SELECT_BCS 0x01 + #define AX_CLK_SELECT_ACS 0x02 + #define AX_CLK_SELECT_ULR 0x08 + +#define AX_RXCOE_CTL 0x34 + #define AX_RXCOE_IP 0x01 + #define AX_RXCOE_TCP 0x02 + #define AX_RXCOE_UDP 0x04 + #define AX_RXCOE_TCPV6 0x20 + #define AX_RXCOE_UDPV6 0x40 + +#define AX_TXCOE_CTL 0x35 + #define AX_TXCOE_IP 0x01 + #define AX_TXCOE_TCP 0x02 + #define AX_TXCOE_UDP 0x04 + #define AX_TXCOE_TCPV6 0x20 + #define AX_TXCOE_UDPV6 0x40 + +#define AX_LEDCTRL 0x73 + +#define GMII_PHY_PHYSR 0x11 + #define GMII_PHY_PHYSR_SMASK 0xc000 + #define GMII_PHY_PHYSR_GIGA 0x8000 + #define GMII_PHY_PHYSR_100 0x4000 + #define GMII_PHY_PHYSR_FULL 0x2000 + #define GMII_PHY_PHYSR_LINK 0x400 + +#define GMII_LED_ACT 0x1a + #define GMII_LED_ACTIVE_MASK 0xff8f + #define GMII_LED0_ACTIVE BIT(4) + #define GMII_LED1_ACTIVE BIT(5) + #define GMII_LED2_ACTIVE BIT(6) + +#define GMII_LED_LINK 0x1c + #define GMII_LED_LINK_MASK 0xf888 + #define GMII_LED0_LINK_10 BIT(0) + #define GMII_LED0_LINK_100 BIT(1) + #define GMII_LED0_LINK_1000 BIT(2) + #define GMII_LED1_LINK_10 BIT(4) + #define GMII_LED1_LINK_100 BIT(5) + #define GMII_LED1_LINK_1000 BIT(6) + #define GMII_LED2_LINK_10 BIT(8) + #define GMII_LED2_LINK_100 BIT(9) + #define GMII_LED2_LINK_1000 BIT(10) + #define LED0_ACTIVE BIT(0) + #define LED0_LINK_10 BIT(1) + #define LED0_LINK_100 BIT(2) + #define LED0_LINK_1000 BIT(3) + #define LED0_FD BIT(4) + #define LED0_USB3_MASK 0x001f + #define LED1_ACTIVE BIT(5) + #define LED1_LINK_10 BIT(6) + #define LED1_LINK_100 BIT(7) + #define LED1_LINK_1000 BIT(8) + #define LED1_FD BIT(9) + #define LED1_USB3_MASK 0x03e0 + #define LED2_ACTIVE BIT(10) + #define LED2_LINK_1000 BIT(13) + #define LED2_LINK_100 BIT(12) + #define LED2_LINK_10 BIT(11) + #define LED2_FD BIT(14) + #define LED_VALID BIT(15) + #define LED2_USB3_MASK 0x7c00 + +#define GMII_PHYPAGE 0x1e +#define GMII_PHY_PAGE_SELECT 0x1f + #define GMII_PHY_PGSEL_EXT 0x0007 + #define GMII_PHY_PGSEL_PAGE0 0x0000 + +struct ax88179_data { + u16 rxctl; + u16 reserved; +}; + +struct ax88179_int_data { + __le32 intdata1; + __le32 intdata2; +}; + +static const struct { + unsigned char ctrl, timer_l, timer_h, size, ifg; +} AX88179_BULKIN_SIZE[] = { + {7, 0x4f, 0, 0x12, 0xff}, + {7, 0x20, 3, 0x16, 0xff}, + {7, 0xae, 7, 0x18, 0xff}, + {7, 0xcc, 0x4c, 0x18, 8}, +}; + +static int __ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data, int in_pm) +{ + int ret; + int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16); + + BUG_ON(!dev); + + if (!in_pm) + fn = usbnet_read_cmd; + else + fn = usbnet_read_cmd_nopm; + + ret = fn(dev, cmd, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, data, size); + + if (unlikely(ret < 0)) + netdev_warn(dev->net, "Failed to read reg index 0x%04x: %d\n", + index, ret); + + return ret; +} + +static int __ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data, int in_pm) +{ + int ret; + int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16); + + BUG_ON(!dev); + + if (!in_pm) + fn = usbnet_write_cmd; + else + fn = usbnet_write_cmd_nopm; + + ret = fn(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, + value, index, data, size); + + if (unlikely(ret < 0)) + netdev_warn(dev->net, "Failed to write reg index 0x%04x: %d\n", + index, ret); + + return ret; +} + +static void ax88179_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, + u16 index, u16 size, void *data) +{ + u16 buf; + + if (2 == size) { + buf = *((u16 *)data); + cpu_to_le16s(&buf); + usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, &buf, + size); + } else { + usbnet_write_cmd_async(dev, cmd, USB_DIR_OUT | USB_TYPE_VENDOR | + USB_RECIP_DEVICE, value, index, data, + size); + } +} + +static int ax88179_read_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, + u16 index, u16 size, void *data) +{ + int ret; + + if (2 == size) { + u16 buf; + ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); + le16_to_cpus(&buf); + *((u16 *)data) = buf; + } else if (4 == size) { + u32 buf; + ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 1); + le32_to_cpus(&buf); + *((u32 *)data) = buf; + } else { + ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 1); + } + + return ret; +} + +static int ax88179_write_cmd_nopm(struct usbnet *dev, u8 cmd, u16 value, + u16 index, u16 size, void *data) +{ + int ret; + + if (2 == size) { + u16 buf; + buf = *((u16 *)data); + cpu_to_le16s(&buf); + ret = __ax88179_write_cmd(dev, cmd, value, index, + size, &buf, 1); + } else { + ret = __ax88179_write_cmd(dev, cmd, value, index, + size, data, 1); + } + + return ret; +} + +static int ax88179_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + int ret; + + if (2 == size) { + u16 buf; + ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); + le16_to_cpus(&buf); + *((u16 *)data) = buf; + } else if (4 == size) { + u32 buf; + ret = __ax88179_read_cmd(dev, cmd, value, index, size, &buf, 0); + le32_to_cpus(&buf); + *((u32 *)data) = buf; + } else { + ret = __ax88179_read_cmd(dev, cmd, value, index, size, data, 0); + } + + return ret; +} + +static int ax88179_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index, + u16 size, void *data) +{ + int ret; + + if (2 == size) { + u16 buf; + buf = *((u16 *)data); + cpu_to_le16s(&buf); + ret = __ax88179_write_cmd(dev, cmd, value, index, + size, &buf, 0); + } else { + ret = __ax88179_write_cmd(dev, cmd, value, index, + size, data, 0); + } + + return ret; +} + +static void ax88179_status(struct usbnet *dev, struct urb *urb) +{ + struct ax88179_int_data *event; + u32 link; + + if (urb->actual_length < 8) + return; + + event = urb->transfer_buffer; + le32_to_cpus((void *)&event->intdata1); + + link = (((__force u32)event->intdata1) & AX_INT_PPLS_LINK) >> 16; + + if (netif_carrier_ok(dev->net) != link) { + if (link) + usbnet_defer_kevent(dev, EVENT_LINK_RESET); + else + netif_carrier_off(dev->net); + + netdev_info(dev->net, "ax88179 - Link status is: %d\n", link); + } +} + +static int ax88179_mdio_read(struct net_device *netdev, int phy_id, int loc) +{ + struct usbnet *dev = netdev_priv(netdev); + u16 res; + + ax88179_read_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); + return res; +} + +static void ax88179_mdio_write(struct net_device *netdev, int phy_id, int loc, + int val) +{ + struct usbnet *dev = netdev_priv(netdev); + u16 res = (u16) val; + + ax88179_write_cmd(dev, AX_ACCESS_PHY, phy_id, (__u16)loc, 2, &res); +} + +static int ax88179_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct usbnet *dev = usb_get_intfdata(intf); + u16 tmp16; + u8 tmp8; + + usbnet_suspend(intf, message); + + /* Disable RX path */ + ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + tmp16 &= ~AX_MEDIUM_RECEIVE_EN; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + + /* Force bulk-in zero length */ + ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, + 2, 2, &tmp16); + + tmp16 |= AX_PHYPWR_RSTCTL_BZ | AX_PHYPWR_RSTCTL_IPRL; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, + 2, 2, &tmp16); + + /* change clock */ + tmp8 = 0; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); + + /* Configure RX control register => stop operation */ + tmp16 = AX_RX_CTL_STOP; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); + + return 0; +} + +/* This function is used to enable the autodetach function. */ +/* This function is determined by offset 0x43 of EEPROM */ +static int ax88179_auto_detach(struct usbnet *dev, int in_pm) +{ + u16 tmp16; + u8 tmp8; + int (*fnr)(struct usbnet *, u8, u16, u16, u16, void *); + int (*fnw)(struct usbnet *, u8, u16, u16, u16, void *); + + if (!in_pm) { + fnr = ax88179_read_cmd; + fnw = ax88179_write_cmd; + } else { + fnr = ax88179_read_cmd_nopm; + fnw = ax88179_write_cmd_nopm; + } + + if (fnr(dev, AX_ACCESS_EEPROM, 0x43, 1, 2, &tmp16) < 0) + return 0; + + if ((tmp16 == 0xFFFF) || (!(tmp16 & 0x0100))) + return 0; + + /* Enable Auto Detach bit */ + tmp8 = 0; + fnr(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); + tmp8 |= AX_CLK_SELECT_ULR; + fnw(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); + + fnr(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); + tmp16 |= AX_PHYPWR_RSTCTL_AT; + fnw(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); + + return 0; +} + +static int ax88179_resume(struct usb_interface *intf) +{ + struct usbnet *dev = usb_get_intfdata(intf); + u16 tmp16; + u8 tmp8; + + netif_carrier_off(dev->net); + + /* Power up ethernet PHY */ + tmp16 = 0; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, + 2, 2, &tmp16); + udelay(1000); + + tmp16 = AX_PHYPWR_RSTCTL_IPRL; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, + 2, 2, &tmp16); + msleep(200); + + /* Ethernet PHY Auto Detach*/ + ax88179_auto_detach(dev, 1); + + /* Enable clock */ + ax88179_read_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); + tmp8 |= AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp8); + msleep(100); + + /* Configure RX control register => start operation */ + tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | + AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; + ax88179_write_cmd_nopm(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); + + return usbnet_resume(intf); +} + +static void +ax88179_get_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +{ + struct usbnet *dev = netdev_priv(net); + u8 opt; + + if (ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, + 1, 1, &opt) < 0) { + wolinfo->supported = 0; + wolinfo->wolopts = 0; + return; + } + + wolinfo->supported = WAKE_PHY | WAKE_MAGIC; + wolinfo->wolopts = 0; + if (opt & AX_MONITOR_MODE_RWLC) + wolinfo->wolopts |= WAKE_PHY; + if (opt & AX_MONITOR_MODE_RWMP) + wolinfo->wolopts |= WAKE_MAGIC; +} + +static int +ax88179_set_wol(struct net_device *net, struct ethtool_wolinfo *wolinfo) +{ + struct usbnet *dev = netdev_priv(net); + u8 opt = 0; + + if (wolinfo->wolopts & WAKE_PHY) + opt |= AX_MONITOR_MODE_RWLC; + if (wolinfo->wolopts & WAKE_MAGIC) + opt |= AX_MONITOR_MODE_RWMP; + + if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, + 1, 1, &opt) < 0) + return -EINVAL; + + return 0; +} + +static int ax88179_get_eeprom_len(struct net_device *net) +{ + return AX_EEPROM_LEN; +} + +static int +ax88179_get_eeprom(struct net_device *net, struct ethtool_eeprom *eeprom, + u8 *data) +{ + struct usbnet *dev = netdev_priv(net); + u16 *eeprom_buff; + int first_word, last_word; + int i, ret; + + if (eeprom->len == 0) + return -EINVAL; + + eeprom->magic = AX88179_EEPROM_MAGIC; + + 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); + if (!eeprom_buff) + return -ENOMEM; + + /* ax88179/178A returns 2 bytes from eeprom on read */ + for (i = first_word; i <= last_word; i++) { + ret = __ax88179_read_cmd(dev, AX_ACCESS_EEPROM, i, 1, 2, + &eeprom_buff[i - first_word], + 0); + if (ret < 0) { + kfree(eeprom_buff); + return -EIO; + } + } + + memcpy(data, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); + kfree(eeprom_buff); + return 0; +} + +static int ax88179_get_settings(struct net_device *net, struct ethtool_cmd *cmd) +{ + struct usbnet *dev = netdev_priv(net); + return mii_ethtool_gset(&dev->mii, cmd); +} + +static int ax88179_set_settings(struct net_device *net, struct ethtool_cmd *cmd) +{ + struct usbnet *dev = netdev_priv(net); + return mii_ethtool_sset(&dev->mii, cmd); +} + + +static int ax88179_ioctl(struct net_device *net, struct ifreq *rq, int cmd) +{ + struct usbnet *dev = netdev_priv(net); + return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); +} + +static const struct ethtool_ops ax88179_ethtool_ops = { + .get_link = ethtool_op_get_link, + .get_msglevel = usbnet_get_msglevel, + .set_msglevel = usbnet_set_msglevel, + .get_wol = ax88179_get_wol, + .set_wol = ax88179_set_wol, + .get_eeprom_len = ax88179_get_eeprom_len, + .get_eeprom = ax88179_get_eeprom, + .get_settings = ax88179_get_settings, + .set_settings = ax88179_set_settings, + .nway_reset = usbnet_nway_reset, +}; + +static void ax88179_set_multicast(struct net_device *net) +{ + struct usbnet *dev = netdev_priv(net); + struct ax88179_data *data = (struct ax88179_data *)dev->data; + u8 *m_filter = ((u8 *)dev->data) + 12; + + data->rxctl = (AX_RX_CTL_START | AX_RX_CTL_AB | AX_RX_CTL_IPE); + + if (net->flags & IFF_PROMISC) { + data->rxctl |= AX_RX_CTL_PRO; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > AX_MAX_MCAST) { + data->rxctl |= AX_RX_CTL_AMALL; + } else if (netdev_mc_empty(net)) { + /* just broadcast and directed */ + } else { + /* We use the 20 byte dev->data for our 8 byte filter buffer + * to avoid allocating memory that is tricky to free later + */ + u32 crc_bits; + struct netdev_hw_addr *ha; + + memset(m_filter, 0, AX_MCAST_FLTSIZE); + + netdev_for_each_mc_addr(ha, net) { + crc_bits = ether_crc(ETH_ALEN, ha->addr) >> 26; + *(m_filter + (crc_bits >> 3)) |= (1 << (crc_bits & 7)); + } + + ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_MULFLTARY, + AX_MCAST_FLTSIZE, AX_MCAST_FLTSIZE, + m_filter); + + data->rxctl |= AX_RX_CTL_AM; + } + + ax88179_write_cmd_async(dev, AX_ACCESS_MAC, AX_RX_CTL, + 2, 2, &data->rxctl); +} + +static int +ax88179_set_features(struct net_device *net, netdev_features_t features) +{ + u8 tmp; + struct usbnet *dev = netdev_priv(net); + netdev_features_t changed = net->features ^ features; + + if (changed & NETIF_F_IP_CSUM) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); + tmp ^= AX_TXCOE_TCP | AX_TXCOE_UDP; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); + } + + if (changed & NETIF_F_IPV6_CSUM) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); + tmp ^= AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, &tmp); + } + + if (changed & NETIF_F_RXCSUM) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); + tmp ^= AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | + AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, &tmp); + } + + return 0; +} + +static int ax88179_change_mtu(struct net_device *net, int new_mtu) +{ + struct usbnet *dev = netdev_priv(net); + u16 tmp16; + + if (new_mtu <= 0 || new_mtu > 4088) + return -EINVAL; + + net->mtu = new_mtu; + dev->hard_mtu = net->mtu + net->hard_header_len; + + if (net->mtu > 1500) { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + tmp16 |= AX_MEDIUM_JUMBO_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + } else { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + tmp16 &= ~AX_MEDIUM_JUMBO_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + } + + return 0; +} + +static int ax88179_set_mac_addr(struct net_device *net, void *p) +{ + struct usbnet *dev = netdev_priv(net); + struct sockaddr *addr = p; + + if (netif_running(net)) + return -EBUSY; + if (!is_valid_ether_addr(addr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(net->dev_addr, addr->sa_data, ETH_ALEN); + + /* Set the MAC address */ + return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, + ETH_ALEN, net->dev_addr); +} + +static const struct net_device_ops ax88179_netdev_ops = { + .ndo_open = usbnet_open, + .ndo_stop = usbnet_stop, + .ndo_start_xmit = usbnet_start_xmit, + .ndo_tx_timeout = usbnet_tx_timeout, + .ndo_change_mtu = ax88179_change_mtu, + .ndo_set_mac_address = ax88179_set_mac_addr, + .ndo_validate_addr = eth_validate_addr, + .ndo_do_ioctl = ax88179_ioctl, + .ndo_set_rx_mode = ax88179_set_multicast, + .ndo_set_features = ax88179_set_features, +}; + +static int ax88179_check_eeprom(struct usbnet *dev) +{ + u8 i, buf, eeprom[20]; + u16 csum, delay = HZ / 10; + unsigned long jtimeout; + + /* Read EEPROM content */ + for (i = 0; i < 6; i++) { + buf = i; + if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR, + 1, 1, &buf) < 0) + return -EINVAL; + + buf = EEP_RD; + if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, + 1, 1, &buf) < 0) + return -EINVAL; + + jtimeout = jiffies + delay; + do { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, + 1, 1, &buf); + + if (time_after(jiffies, jtimeout)) + return -EINVAL; + + } while (buf & EEP_BUSY); + + __ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW, + 2, 2, &eeprom[i * 2], 0); + + if ((i == 0) && (eeprom[0] == 0xFF)) + return -EINVAL; + } + + csum = eeprom[6] + eeprom[7] + eeprom[8] + eeprom[9]; + csum = (csum >> 8) + (csum & 0xff); + if ((csum + eeprom[10]) != 0xff) + return -EINVAL; + + return 0; +} + +static int ax88179_check_efuse(struct usbnet *dev, u16 *ledmode) +{ + u8 i; + u8 efuse[64]; + u16 csum = 0; + + if (ax88179_read_cmd(dev, AX_ACCESS_EFUS, 0, 64, 64, efuse) < 0) + return -EINVAL; + + if (*efuse == 0xFF) + return -EINVAL; + + for (i = 0; i < 64; i++) + csum = csum + efuse[i]; + + while (csum > 255) + csum = (csum & 0x00FF) + ((csum >> 8) & 0x00FF); + + if (csum != 0xFF) + return -EINVAL; + + *ledmode = (efuse[51] << 8) | efuse[52]; + + return 0; +} + +static int ax88179_convert_old_led(struct usbnet *dev, u16 *ledvalue) +{ + u16 led; + + /* Loaded the old eFuse LED Mode */ + if (ax88179_read_cmd(dev, AX_ACCESS_EEPROM, 0x3C, 1, 2, &led) < 0) + return -EINVAL; + + led >>= 8; + switch (led) { + case 0xFF: + led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 | + LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 | + LED2_LINK_100 | LED2_LINK_1000 | LED_VALID; + break; + case 0xFE: + led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | LED_VALID; + break; + case 0xFD: + led = LED0_ACTIVE | LED1_LINK_1000 | LED2_LINK_100 | + LED2_LINK_10 | LED_VALID; + break; + case 0xFC: + led = LED0_ACTIVE | LED1_ACTIVE | LED1_LINK_1000 | LED2_ACTIVE | + LED2_LINK_100 | LED2_LINK_10 | LED_VALID; + break; + default: + led = LED0_ACTIVE | LED1_LINK_10 | LED1_LINK_100 | + LED1_LINK_1000 | LED2_ACTIVE | LED2_LINK_10 | + LED2_LINK_100 | LED2_LINK_1000 | LED_VALID; + break; + } + + *ledvalue = led; + + return 0; +} + +static int ax88179_led_setting(struct usbnet *dev) +{ + u8 ledfd, value = 0; + u16 tmp, ledact, ledlink, ledvalue = 0, delay = HZ / 10; + unsigned long jtimeout; + + /* Check AX88179 version. UA1 or UA2*/ + ax88179_read_cmd(dev, AX_ACCESS_MAC, GENERAL_STATUS, 1, 1, &value); + + if (!(value & AX_SECLD)) { /* UA1 */ + value = AX_GPIO_CTRL_GPIO3EN | AX_GPIO_CTRL_GPIO2EN | + AX_GPIO_CTRL_GPIO1EN; + if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_GPIO_CTRL, + 1, 1, &value) < 0) + return -EINVAL; + } + + /* Check EEPROM */ + if (!ax88179_check_eeprom(dev)) { + value = 0x42; + if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_ADDR, + 1, 1, &value) < 0) + return -EINVAL; + + value = EEP_RD; + if (ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, + 1, 1, &value) < 0) + return -EINVAL; + + jtimeout = jiffies + delay; + do { + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_CMD, + 1, 1, &value); + + if (time_after(jiffies, jtimeout)) + return -EINVAL; + + } while (value & EEP_BUSY); + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_HIGH, + 1, 1, &value); + ledvalue = (value << 8); + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_SROM_DATA_LOW, + 1, 1, &value); + ledvalue |= value; + + /* load internal ROM for defaule setting */ + if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0)) + ax88179_convert_old_led(dev, &ledvalue); + + } else if (!ax88179_check_efuse(dev, &ledvalue)) { + if ((ledvalue == 0xFFFF) || ((ledvalue & LED_VALID) == 0)) + ax88179_convert_old_led(dev, &ledvalue); + } else { + ax88179_convert_old_led(dev, &ledvalue); + } + + tmp = GMII_PHY_PGSEL_EXT; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHY_PAGE_SELECT, 2, &tmp); + + tmp = 0x2c; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHYPAGE, 2, &tmp); + + ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_LED_ACT, 2, &ledact); + + ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_LED_LINK, 2, &ledlink); + + ledact &= GMII_LED_ACTIVE_MASK; + ledlink &= GMII_LED_LINK_MASK; + + if (ledvalue & LED0_ACTIVE) + ledact |= GMII_LED0_ACTIVE; + + if (ledvalue & LED1_ACTIVE) + ledact |= GMII_LED1_ACTIVE; + + if (ledvalue & LED2_ACTIVE) + ledact |= GMII_LED2_ACTIVE; + + if (ledvalue & LED0_LINK_10) + ledlink |= GMII_LED0_LINK_10; + + if (ledvalue & LED1_LINK_10) + ledlink |= GMII_LED1_LINK_10; + + if (ledvalue & LED2_LINK_10) + ledlink |= GMII_LED2_LINK_10; + + if (ledvalue & LED0_LINK_100) + ledlink |= GMII_LED0_LINK_100; + + if (ledvalue & LED1_LINK_100) + ledlink |= GMII_LED1_LINK_100; + + if (ledvalue & LED2_LINK_100) + ledlink |= GMII_LED2_LINK_100; + + if (ledvalue & LED0_LINK_1000) + ledlink |= GMII_LED0_LINK_1000; + + if (ledvalue & LED1_LINK_1000) + ledlink |= GMII_LED1_LINK_1000; + + if (ledvalue & LED2_LINK_1000) + ledlink |= GMII_LED2_LINK_1000; + + tmp = ledact; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_LED_ACT, 2, &tmp); + + tmp = ledlink; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_LED_LINK, 2, &tmp); + + tmp = GMII_PHY_PGSEL_PAGE0; + ax88179_write_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHY_PAGE_SELECT, 2, &tmp); + + /* LED full duplex setting */ + ledfd = 0; + if (ledvalue & LED0_FD) + ledfd |= 0x01; + else if ((ledvalue & LED0_USB3_MASK) == 0) + ledfd |= 0x02; + + if (ledvalue & LED1_FD) + ledfd |= 0x04; + else if ((ledvalue & LED1_USB3_MASK) == 0) + ledfd |= 0x08; + + if (ledvalue & LED2_FD) + ledfd |= 0x10; + else if ((ledvalue & LED2_USB3_MASK) == 0) + ledfd |= 0x20; + + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_LEDCTRL, 1, 1, &ledfd); + + return 0; +} + +static int ax88179_bind(struct usbnet *dev, struct usb_interface *intf) +{ + u8 buf[5]; + u16 *tmp16; + u8 *tmp; + struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; + + usbnet_get_endpoints(dev, intf); + + tmp16 = (u16 *)buf; + tmp = (u8 *)buf; + + memset(ax179_data, 0, sizeof(*ax179_data)); + + /* Power up ethernet PHY */ + *tmp16 = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + *tmp16 = AX_PHYPWR_RSTCTL_IPRL; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + msleep(200); + + *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); + msleep(100); + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, + ETH_ALEN, dev->net->dev_addr); + memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); + + /* RX bulk configuration */ + memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); + + dev->rx_urb_size = 1024 * 20; + + *tmp = 0x34; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + + *tmp = 0x52; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, + 1, 1, tmp); + + dev->net->netdev_ops = &ax88179_netdev_ops; + dev->net->ethtool_ops = &ax88179_ethtool_ops; + dev->net->needed_headroom = 8; + + /* Initialize MII structure */ + dev->mii.dev = dev->net; + dev->mii.mdio_read = ax88179_mdio_read; + dev->mii.mdio_write = ax88179_mdio_write; + dev->mii.phy_id_mask = 0xff; + dev->mii.reg_num_mask = 0xff; + dev->mii.phy_id = 0x03; + dev->mii.supports_gmii = 1; + + dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + + dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + + /* Enable checksum offload */ + *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | + AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); + + *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | + AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); + + /* Configure RX control register => start operation */ + *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | + AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); + + *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | + AX_MONITOR_MODE_RWMP; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); + + /* Configure default medium type => giga */ + *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | + AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE | + AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, tmp16); + + ax88179_led_setting(dev); + + /* Restart autoneg */ + mii_nway_restart(&dev->mii); + + netif_carrier_off(dev->net); + + return 0; +} + +static void ax88179_unbind(struct usbnet *dev, struct usb_interface *intf) +{ + u16 tmp16; + + /* Configure RX control register => stop operation */ + tmp16 = AX_RX_CTL_STOP; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &tmp16); + + tmp16 = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, &tmp16); + + /* Power down ethernet PHY */ + tmp16 = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, &tmp16); +} + +static void +ax88179_rx_checksum(struct sk_buff *skb, u32 *pkt_hdr) +{ + skb->ip_summed = CHECKSUM_NONE; + + /* checksum error bit is set */ + if ((*pkt_hdr & AX_RXHDR_L3CSUM_ERR) || + (*pkt_hdr & AX_RXHDR_L4CSUM_ERR)) + return; + + /* It must be a TCP or UDP packet with a valid checksum */ + if (((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_TCP) || + ((*pkt_hdr & AX_RXHDR_L4_TYPE_MASK) == AX_RXHDR_L4_TYPE_UDP)) + skb->ip_summed = CHECKSUM_UNNECESSARY; +} + +static int ax88179_rx_fixup(struct usbnet *dev, struct sk_buff *skb) +{ + struct sk_buff *ax_skb; + int pkt_cnt; + u32 rx_hdr; + u16 hdr_off; + u32 *pkt_hdr; + + skb_trim(skb, skb->len - 4); + memcpy(&rx_hdr, skb_tail_pointer(skb), 4); + le32_to_cpus(&rx_hdr); + + pkt_cnt = (u16)rx_hdr; + hdr_off = (u16)(rx_hdr >> 16); + pkt_hdr = (u32 *)(skb->data + hdr_off); + + while (pkt_cnt--) { + u16 pkt_len; + + le32_to_cpus(pkt_hdr); + pkt_len = (*pkt_hdr >> 16) & 0x1fff; + + /* Check CRC or runt packet */ + if ((*pkt_hdr & AX_RXHDR_CRC_ERR) || + (*pkt_hdr & AX_RXHDR_DROP_ERR)) { + skb_pull(skb, (pkt_len + 7) & 0xFFF8); + pkt_hdr++; + continue; + } + + if (pkt_cnt == 0) { + /* Skip IP alignment psudo header */ + skb_pull(skb, 2); + skb->len = pkt_len; + skb_set_tail_pointer(skb, pkt_len); + skb->truesize = pkt_len + sizeof(struct sk_buff); + ax88179_rx_checksum(skb, pkt_hdr); + return 1; + } + + ax_skb = skb_clone(skb, GFP_ATOMIC); + if (ax_skb) { + ax_skb->len = pkt_len; + ax_skb->data = skb->data + 2; + skb_set_tail_pointer(ax_skb, pkt_len); + ax_skb->truesize = pkt_len + sizeof(struct sk_buff); + ax88179_rx_checksum(ax_skb, pkt_hdr); + usbnet_skb_return(dev, ax_skb); + } else { + return 0; + } + + skb_pull(skb, (pkt_len + 7) & 0xFFF8); + pkt_hdr++; + } + return 1; +} + +static struct sk_buff * +ax88179_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) +{ + u32 tx_hdr1, tx_hdr2; + int frame_size = dev->maxpacket; + int mss = skb_shinfo(skb)->gso_size; + int headroom; + int tailroom; + + tx_hdr1 = skb->len; + tx_hdr2 = mss; + if (((skb->len + 8) % frame_size) == 0) + tx_hdr2 |= 0x80008000; /* Enable padding */ + + skb_linearize(skb); + headroom = skb_headroom(skb); + tailroom = skb_tailroom(skb); + + if (!skb_header_cloned(skb) && + !skb_cloned(skb) && + (headroom + tailroom) >= 8) { + if (headroom < 8) { + skb->data = memmove(skb->head + 8, skb->data, skb->len); + skb_set_tail_pointer(skb, skb->len); + } + } else { + struct sk_buff *skb2; + + skb2 = skb_copy_expand(skb, 8, 0, flags); + dev_kfree_skb_any(skb); + skb = skb2; + if (!skb) + return NULL; + } + + skb_push(skb, 4); + cpu_to_le32s(&tx_hdr2); + skb_copy_to_linear_data(skb, &tx_hdr2, 4); + + skb_push(skb, 4); + cpu_to_le32s(&tx_hdr1); + skb_copy_to_linear_data(skb, &tx_hdr1, 4); + + return skb; +} + +static int ax88179_link_reset(struct usbnet *dev) +{ + struct ax88179_data *ax179_data = (struct ax88179_data *)dev->data; + u8 tmp[5], link_sts; + u16 mode, tmp16, delay = HZ / 10; + u32 tmp32 = 0x40000000; + unsigned long jtimeout; + + jtimeout = jiffies + delay; + while (tmp32 & 0x40000000) { + mode = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, &mode); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, + &ax179_data->rxctl); + + /*link up, check the usb device control TX FIFO full or empty*/ + ax88179_read_cmd(dev, 0x81, 0x8c, 0, 4, &tmp32); + + if (time_after(jiffies, jtimeout)) + return 0; + } + + mode = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | + AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE; + + ax88179_read_cmd(dev, AX_ACCESS_MAC, PHYSICAL_LINK_STATUS, + 1, 1, &link_sts); + + ax88179_read_cmd(dev, AX_ACCESS_PHY, AX88179_PHY_ID, + GMII_PHY_PHYSR, 2, &tmp16); + + if (!(tmp16 & GMII_PHY_PHYSR_LINK)) { + return 0; + } else if (GMII_PHY_PHYSR_GIGA == (tmp16 & GMII_PHY_PHYSR_SMASK)) { + mode |= AX_MEDIUM_GIGAMODE | AX_MEDIUM_EN_125MHZ; + if (dev->net->mtu > 1500) + mode |= AX_MEDIUM_JUMBO_EN; + + if (link_sts & AX_USB_SS) + memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); + else if (link_sts & AX_USB_HS) + memcpy(tmp, &AX88179_BULKIN_SIZE[1], 5); + else + memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); + } else if (GMII_PHY_PHYSR_100 == (tmp16 & GMII_PHY_PHYSR_SMASK)) { + mode |= AX_MEDIUM_PS; + + if (link_sts & (AX_USB_SS | AX_USB_HS)) + memcpy(tmp, &AX88179_BULKIN_SIZE[2], 5); + else + memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); + } else { + memcpy(tmp, &AX88179_BULKIN_SIZE[3], 5); + } + + /* RX bulk configuration */ + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); + + dev->rx_urb_size = (1024 * (tmp[3] + 2)); + + if (tmp16 & GMII_PHY_PHYSR_FULL) + mode |= AX_MEDIUM_FULL_DUPLEX; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &mode); + + netif_carrier_on(dev->net); + + return 0; +} + +static int ax88179_reset(struct usbnet *dev) +{ + u8 buf[5]; + u16 *tmp16; + u8 *tmp; + + tmp16 = (u16 *)buf; + tmp = (u8 *)buf; + + /* Power up ethernet PHY */ + *tmp16 = 0; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + + *tmp16 = AX_PHYPWR_RSTCTL_IPRL; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PHYPWR_RSTCTL, 2, 2, tmp16); + msleep(200); + + *tmp = AX_CLK_SELECT_ACS | AX_CLK_SELECT_BCS; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_CLK_SELECT, 1, 1, tmp); + msleep(100); + + /* Ethernet PHY Auto Detach*/ + ax88179_auto_detach(dev, 0); + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN, ETH_ALEN, + dev->net->dev_addr); + memcpy(dev->net->perm_addr, dev->net->dev_addr, ETH_ALEN); + + /* RX bulk configuration */ + memcpy(tmp, &AX88179_BULKIN_SIZE[0], 5); + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_BULKIN_QCTRL, 5, 5, tmp); + + dev->rx_urb_size = 1024 * 20; + + *tmp = 0x34; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_LOW, 1, 1, tmp); + + *tmp = 0x52; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_PAUSE_WATERLVL_HIGH, + 1, 1, tmp); + + dev->net->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + + dev->net->hw_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_TSO; + + /* Enable checksum offload */ + *tmp = AX_RXCOE_IP | AX_RXCOE_TCP | AX_RXCOE_UDP | + AX_RXCOE_TCPV6 | AX_RXCOE_UDPV6; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RXCOE_CTL, 1, 1, tmp); + + *tmp = AX_TXCOE_IP | AX_TXCOE_TCP | AX_TXCOE_UDP | + AX_TXCOE_TCPV6 | AX_TXCOE_UDPV6; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_TXCOE_CTL, 1, 1, tmp); + + /* Configure RX control register => start operation */ + *tmp16 = AX_RX_CTL_DROPCRCERR | AX_RX_CTL_IPE | AX_RX_CTL_START | + AX_RX_CTL_AP | AX_RX_CTL_AMALL | AX_RX_CTL_AB; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_RX_CTL, 2, 2, tmp16); + + *tmp = AX_MONITOR_MODE_PMETYPE | AX_MONITOR_MODE_PMEPOL | + AX_MONITOR_MODE_RWMP; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MONITOR_MOD, 1, 1, tmp); + + /* Configure default medium type => giga */ + *tmp16 = AX_MEDIUM_RECEIVE_EN | AX_MEDIUM_TXFLOW_CTRLEN | + AX_MEDIUM_RXFLOW_CTRLEN | AX_MEDIUM_ALWAYS_ONE | + AX_MEDIUM_FULL_DUPLEX | AX_MEDIUM_GIGAMODE; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, tmp16); + + ax88179_led_setting(dev); + + /* Restart autoneg */ + mii_nway_restart(&dev->mii); + + netif_carrier_off(dev->net); + + return 0; +} + +static int ax88179_stop(struct usbnet *dev) +{ + u16 tmp16; + + ax88179_read_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + tmp16 &= ~AX_MEDIUM_RECEIVE_EN; + ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_MEDIUM_STATUS_MODE, + 2, 2, &tmp16); + + return 0; +} + +static const struct driver_info ax88179_info = { + .description = "ASIX AX88179 USB 3.0 Gigibit Ethernet", + .bind = ax88179_bind, + .unbind = ax88179_unbind, + .status = ax88179_status, + .link_reset = ax88179_link_reset, + .reset = ax88179_reset, + .stop = ax88179_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .rx_fixup = ax88179_rx_fixup, + .tx_fixup = ax88179_tx_fixup, +}; + +static const struct driver_info ax88178a_info = { + .description = "ASIX AX88178A USB 2.0 Gigibit Ethernet", + .bind = ax88179_bind, + .unbind = ax88179_unbind, + .status = ax88179_status, + .link_reset = ax88179_link_reset, + .reset = ax88179_reset, + .stop = ax88179_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .rx_fixup = ax88179_rx_fixup, + .tx_fixup = ax88179_tx_fixup, +}; + +static const struct driver_info sitecom_info = { + .description = "Sitecom USB 3.0 to Gigabit Adapter", + .bind = ax88179_bind, + .unbind = ax88179_unbind, + .status = ax88179_status, + .link_reset = ax88179_link_reset, + .reset = ax88179_reset, + .stop = ax88179_stop, + .flags = FLAG_ETHER | FLAG_FRAMING_AX, + .rx_fixup = ax88179_rx_fixup, + .tx_fixup = ax88179_tx_fixup, +}; + +static const struct usb_device_id products[] = { +{ + /* ASIX AX88179 10/100/1000 */ + USB_DEVICE(0x0b95, 0x1790), + .driver_info = (unsigned long)&ax88179_info, +}, { + /* ASIX AX88178A 10/100/1000 */ + USB_DEVICE(0x0b95, 0x178a), + .driver_info = (unsigned long)&ax88178a_info, +}, { + /* Sitecom USB 3.0 to Gigabit Adapter */ + USB_DEVICE(0x0df6, 0x0072), + .driver_info = (unsigned long) &sitecom_info, +}, + { }, +}; +MODULE_DEVICE_TABLE(usb, products); + +static struct usb_driver ax88179_178a_driver = { + .name = "ax88179_178a", + .id_table = products, + .probe = usbnet_probe, + .suspend = ax88179_suspend, + .resume = ax88179_resume, + .disconnect = usbnet_disconnect, + .supports_autosuspend = 1, + .disable_hub_initiated_lpm = 1, +}; + +module_usb_driver(ax88179_178a_driver); + +MODULE_DESCRIPTION("ASIX AX88179/178A based USB 3.0/2.0 Gigabit Ethernet Devices"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From f3e227df8235fc0bf8ba08304aa135066ec9b9b0 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Mon, 25 Feb 2013 04:05:38 +0530 Subject: drm/i915: Fix missing variable initilization Need to initialize the variable wait to false. Signed-off-by: Syam Sidhardhan Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_ddi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 816c45c71b72..24debd6066a7 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -1391,8 +1391,8 @@ void intel_ddi_prepare_link_retrain(struct drm_encoder *encoder) struct intel_dp *intel_dp = &intel_dig_port->dp; struct drm_i915_private *dev_priv = encoder->dev->dev_private; enum port port = intel_dig_port->port; - bool wait; uint32_t val; + bool wait = false; if (I915_READ(DP_TP_CTL(port)) & DP_TP_CTL_ENABLE) { val = I915_READ(DDI_BUF_CTL(port)); -- cgit v1.2.3 From b18ac466956c7e7b5abf7a2d6adf8c626267d0ae Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Mon, 18 Feb 2013 19:00:24 -0300 Subject: drm/i915: wait_event_timeout's timeout is in jiffies So use msecs_to_jiffies(10) to make the timeout the same as in the "!has_aux_irq" case. This patch was initially written by Daniel Vetter and posted on pastebin a few weeks ago. I'm just bringing it to the mailing list. Signed-off-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 7b8bfe8982e6..50cd7ac28c2c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -353,7 +353,8 @@ intel_dp_aux_wait_done(struct intel_dp *intel_dp, bool has_aux_irq) #define C (((status = I915_READ_NOTRACE(ch_ctl)) & DP_AUX_CH_CTL_SEND_BUSY) == 0) if (has_aux_irq) - done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, 10); + done = wait_event_timeout(dev_priv->gmbus_wait_queue, C, + msecs_to_jiffies(10)); else done = wait_for_atomic(C, 10) == 0; if (!done) -- cgit v1.2.3 From 4a35f83b2b7c6aae3fc0d1c4554fdc99dc33ad07 Mon Sep 17 00:00:00 2001 From: Ville Syrjälä Date: Fri, 22 Feb 2013 16:53:38 +0200 Subject: drm/i915: Don't clobber crtc->fb when queue_flip fails MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restore crtc->fb to the old framebuffer if queue_flip fails. While at it, kill the pointless intel_fb temp variable. v2: Update crtc->fb before queue_flip and restore it back after a failure. Cc: stable@vger.kernel.org Signed-off-by: Ville Syrjälä Reviewed-by: Chris Wilson Reported-and-Tested-by: Mika Kuoppala Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0ff10b3af9ea..09659ff6d24d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -7264,8 +7264,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj; + struct drm_framebuffer *old_fb = crtc->fb; + struct drm_i915_gem_object *obj = to_intel_framebuffer(fb)->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; unsigned long flags; @@ -7290,8 +7290,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, work->event = event; work->crtc = crtc; - intel_fb = to_intel_framebuffer(crtc->fb); - work->old_fb_obj = intel_fb->obj; + work->old_fb_obj = to_intel_framebuffer(old_fb)->obj; INIT_WORK(&work->work, intel_unpin_work_fn); ret = drm_vblank_get(dev, intel_crtc->pipe); @@ -7311,9 +7310,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, intel_crtc->unpin_work = work; spin_unlock_irqrestore(&dev->event_lock, flags); - intel_fb = to_intel_framebuffer(fb); - obj = intel_fb->obj; - if (atomic_read(&intel_crtc->unpin_work_count) >= 2) flush_workqueue(dev_priv->wq); @@ -7348,6 +7344,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); + crtc->fb = old_fb; drm_gem_object_unreference(&work->old_fb_obj->base); drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From 86c268ed0f9b3b4d51d81dd8fcec533a164414d1 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Fri, 1 Mar 2013 17:00:50 -0800 Subject: drm/i915: Fix Haswell/CRW PCI IDs. The second digit was off by one, which meant we accidentally treated GT(n) as GT(n-1). This also meant no support for GT1 at all. Cc: stable@kernel.org Signed-off-by: Kenneth Graunke Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index c5b8c81b9440..2c5ee965e473 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -379,15 +379,15 @@ static const struct pci_device_id pciidlist[] = { /* aka */ INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ - INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ + INTEL_VGA_DEVICE(0x0D02, &intel_haswell_d_info), /* CRW GT1 desktop */ + INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT2 desktop */ INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ - INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ - INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ + INTEL_VGA_DEVICE(0x0D0A, &intel_haswell_d_info), /* CRW GT1 server */ + INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT2 server */ INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ - INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ - INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ + INTEL_VGA_DEVICE(0x0D06, &intel_haswell_m_info), /* CRW GT1 mobile */ + INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT2 mobile */ INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ - INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), -- cgit v1.2.3 From 65b5f42e2a9eb9c8383fb67698bf8c27657f8c14 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Feb 2013 16:47:44 +1000 Subject: drm/nve0/graph: some random reg moved on kepler Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/graph/nve0.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c index 61cec0f6ff1c..4857f913efdd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nve0.c @@ -350,7 +350,7 @@ nve0_graph_init_gpc_0(struct nvc0_graph_priv *priv) nv_wr32(priv, GPC_UNIT(gpc, 0x0918), magicgpc918); } - nv_wr32(priv, GPC_BCAST(0x1bd4), magicgpc918); + nv_wr32(priv, GPC_BCAST(0x3fd4), magicgpc918); nv_wr32(priv, GPC_BCAST(0x08ac), nv_rd32(priv, 0x100800)); } -- cgit v1.2.3 From 650e1203c11354ba84d69ba445abc0efcfe3890a Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 26 Feb 2013 02:33:11 +0100 Subject: drm/nouveau: Disable AGP on PowerPC again. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_agp.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c index d28430cd2ba6..6e7a55f93a85 100644 --- a/drivers/gpu/drm/nouveau/nouveau_agp.c +++ b/drivers/gpu/drm/nouveau/nouveau_agp.c @@ -47,6 +47,18 @@ nouveau_agp_enabled(struct nouveau_drm *drm) if (drm->agp.stat == UNKNOWN) { if (!nouveau_agpmode) return false; +#ifdef __powerpc__ + /* Disable AGP by default on all PowerPC machines for + * now -- At least some UniNorth-2 AGP bridges are + * known to be broken: DMA from the host to the card + * works just fine, but writeback from the card to the + * host goes straight to memory untranslated bypassing + * the GATT somehow, making them quite painful to deal + * with... + */ + if (nouveau_agpmode == -1) + return false; +#endif return true; } -- cgit v1.2.3 From f6853faa85793bf23b46787e4039824d275453c2 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Tue, 26 Feb 2013 02:33:12 +0100 Subject: drm/nouveau: Fix typo in init_idx_addr_latched(). Fixes script-based modesetting on some LVDS panels. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 2cc1e6a5eb6a..9c41b58d57e2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -869,7 +869,7 @@ init_idx_addr_latched(struct nvbios_init *init) init->offset += 2; init_wr32(init, dreg, idata); - init_mask(init, creg, ~mask, data | idata); + init_mask(init, creg, ~mask, data | iaddr); } } -- cgit v1.2.3 From 67f9718b084ea7100cefa39b02863fcb14102f8c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 26 Feb 2013 12:02:54 +1000 Subject: drm/nv84: fix regression in page flipping Need to emit the semaphore ctxdma before trying to use the semaphore operations. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index a6237c9cbbc3..e26caf63db0c 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -512,11 +512,11 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, /* synchronise with the rendering channel, if necessary */ if (likely(chan)) { - ret = RING_SPACE(chan, 10); - if (ret) - return ret; - if (nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { + ret = RING_SPACE(chan, 8); + if (ret) + return ret; + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); OUT_RING (chan, NvEvoSema0 + nv_crtc->index); OUT_RING (chan, sync->sem.offset); @@ -525,13 +525,17 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); OUT_RING (chan, sync->sem.offset ^ 0x10); OUT_RING (chan, 0x74b1e000); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, NvSema); } else if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { u64 offset = nv84_fence_crtc(chan, nv_crtc->index); offset += sync->sem.offset; + ret = RING_SPACE(chan, 12); + if (ret) + return ret; + + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); + OUT_RING (chan, chan->vram); BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); OUT_RING (chan, upper_32_bits(offset)); OUT_RING (chan, lower_32_bits(offset)); @@ -546,6 +550,10 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, u64 offset = nv84_fence_crtc(chan, nv_crtc->index); offset += sync->sem.offset; + ret = RING_SPACE(chan, 10); + if (ret) + return ret; + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); OUT_RING (chan, upper_32_bits(offset)); OUT_RING (chan, lower_32_bits(offset)); -- cgit v1.2.3 From 42bed34c364786b3757f9d788d8ed39120e8f1b5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 27 Feb 2013 09:52:47 +1000 Subject: drm/nouveau/i2c: drop parent refcount when creating ports Fixes issue where i2c subdev never gets destroyed due to its subobjects holding references. This will mean the i2c subdev refcount goes negative during its destruction, but this isn't an issue in practice. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/i2c/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index a114a0ed7e98..2e98e8a3f1aa 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -142,6 +142,7 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, /* drop port's i2c subdev refcount, i2c handles this itself */ if (ret == 0) { list_add_tail(&port->head, &i2c->ports); + atomic_dec(&parent->refcount); atomic_dec(&engine->refcount); } -- cgit v1.2.3 From 9f9bdaaf07dee47f73a160e6e4c64f67ee26c1d7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sat, 2 Mar 2013 13:21:31 +1000 Subject: drm/nv50-: prevent some races between modesetting and page flipping nexuiz-glx + gnome-shell is able to trigger this a lot of the time. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 189 ++++++++++++++++++--------------- 1 file changed, 106 insertions(+), 83 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e26caf63db0c..87a5a56ed358 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -55,9 +55,9 @@ /* offsets in shared sync bo of various structures */ #define EVO_SYNC(c, o) ((c) * 0x0100 + (o)) -#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) -#define EVO_FLIP_SEM0(c) EVO_SYNC((c), 0x00) -#define EVO_FLIP_SEM1(c) EVO_SYNC((c), 0x10) +#define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) +#define EVO_FLIP_SEM0(c) EVO_SYNC((c) + 1, 0x00) +#define EVO_FLIP_SEM1(c) EVO_SYNC((c) + 1, 0x10) #define EVO_CORE_HANDLE (0xd1500000) #define EVO_CHAN_HANDLE(t,i) (0xd15c0000 | (((t) & 0x00ff) << 8) | (i)) @@ -341,10 +341,8 @@ struct nv50_curs { struct nv50_sync { struct nv50_dmac base; - struct { - u32 offset; - u16 value; - } sem; + u32 addr; + u32 data; }; struct nv50_ovly { @@ -471,13 +469,33 @@ nv50_display_crtc_sema(struct drm_device *dev, int crtc) return nv50_disp(dev)->sync; } +struct nv50_display_flip { + struct nv50_disp *disp; + struct nv50_sync *chan; +}; + +static bool +nv50_display_flip_wait(void *data) +{ + struct nv50_display_flip *flip = data; + if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) == + flip->chan->data); + return true; + usleep_range(1, 2); + return false; +} + void nv50_display_flip_stop(struct drm_crtc *crtc) { - struct nv50_sync *sync = nv50_sync(crtc); + struct nouveau_device *device = nouveau_dev(crtc->dev); + struct nv50_display_flip flip = { + .disp = nv50_disp(crtc->dev), + .chan = nv50_sync(crtc), + }; u32 *push; - push = evo_wait(sync, 8); + push = evo_wait(flip.chan, 8); if (push) { evo_mthd(push, 0x0084, 1); evo_data(push, 0x00000000); @@ -487,8 +505,10 @@ nv50_display_flip_stop(struct drm_crtc *crtc) evo_data(push, 0x00000000); evo_mthd(push, 0x0080, 1); evo_data(push, 0x00000000); - evo_kick(push, sync); + evo_kick(push, flip.chan); } + + nv_wait_cb(device, nv50_display_flip_wait, &flip); } int @@ -496,11 +516,10 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct nouveau_channel *chan, u32 swap_interval) { struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); - struct nv50_disp *disp = nv50_disp(crtc->dev); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nv50_sync *sync = nv50_sync(crtc); + int head = nv_crtc->index, ret; u32 *push; - int ret; swap_interval <<= 4; if (swap_interval == 0) @@ -510,66 +529,64 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, if (unlikely(push == NULL)) return -EBUSY; - /* synchronise with the rendering channel, if necessary */ - if (likely(chan)) { - if (nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { - ret = RING_SPACE(chan, 8); - if (ret) - return ret; - - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); - OUT_RING (chan, NvEvoSema0 + nv_crtc->index); - OUT_RING (chan, sync->sem.offset); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); - OUT_RING (chan, 0xf00d0000 | sync->sem.value); - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); - OUT_RING (chan, sync->sem.offset ^ 0x10); - OUT_RING (chan, 0x74b1e000); - } else - if (nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { - u64 offset = nv84_fence_crtc(chan, nv_crtc->index); - offset += sync->sem.offset; - - ret = RING_SPACE(chan, 12); - if (ret) - return ret; - - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); - OUT_RING (chan, chan->vram); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 0xf00d0000 | sync->sem.value); - OUT_RING (chan, 0x00000002); - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset ^ 0x10)); - OUT_RING (chan, 0x74b1e000); - OUT_RING (chan, 0x00000001); - } else { - u64 offset = nv84_fence_crtc(chan, nv_crtc->index); - offset += sync->sem.offset; - - ret = RING_SPACE(chan, 10); - if (ret) - return ret; - - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset)); - OUT_RING (chan, 0xf00d0000 | sync->sem.value); - OUT_RING (chan, 0x00001002); - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); - OUT_RING (chan, upper_32_bits(offset)); - OUT_RING (chan, lower_32_bits(offset ^ 0x10)); - OUT_RING (chan, 0x74b1e000); - OUT_RING (chan, 0x00001001); - } + if (chan && nv_mclass(chan->object) < NV84_CHANNEL_IND_CLASS) { + ret = RING_SPACE(chan, 8); + if (ret) + return ret; + + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); + OUT_RING (chan, NvEvoSema0 + head); + OUT_RING (chan, sync->addr ^ 0x10); + BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); + OUT_RING (chan, sync->data + 1); + BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); + OUT_RING (chan, sync->addr); + OUT_RING (chan, sync->data); + } else + if (chan && nv_mclass(chan->object) < NVC0_CHANNEL_IND_CLASS) { + u64 addr = nv84_fence_crtc(chan, head) + sync->addr; + ret = RING_SPACE(chan, 12); + if (ret) + return ret; + + BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); + OUT_RING (chan, chan->vram); + BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(addr ^ 0x10)); + OUT_RING (chan, lower_32_bits(addr ^ 0x10)); + OUT_RING (chan, sync->data + 1); + OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); + BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(addr)); + OUT_RING (chan, lower_32_bits(addr)); + OUT_RING (chan, sync->data); + OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); + } else + if (chan) { + u64 addr = nv84_fence_crtc(chan, head) + sync->addr; + ret = RING_SPACE(chan, 10); + if (ret) + return ret; + + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(addr ^ 0x10)); + OUT_RING (chan, lower_32_bits(addr ^ 0x10)); + OUT_RING (chan, sync->data + 1); + OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG | + NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); + BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); + OUT_RING (chan, upper_32_bits(addr)); + OUT_RING (chan, lower_32_bits(addr)); + OUT_RING (chan, sync->data); + OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL | + NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); + } + if (chan) { + sync->addr ^= 0x10; + sync->data++; FIRE_RING (chan); } else { - nouveau_bo_wr32(disp->sync, sync->sem.offset / 4, - 0xf00d0000 | sync->sem.value); evo_sync(crtc->dev); } @@ -583,9 +600,9 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, evo_data(push, 0x40000000); } evo_mthd(push, 0x0088, 4); - evo_data(push, sync->sem.offset); - evo_data(push, 0xf00d0000 | sync->sem.value); - evo_data(push, 0x74b1e000); + evo_data(push, sync->addr); + evo_data(push, sync->data++); + evo_data(push, sync->data); evo_data(push, NvEvoSync); evo_mthd(push, 0x00a0, 2); evo_data(push, 0x00000000); @@ -613,9 +630,6 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, evo_mthd(push, 0x0080, 1); evo_data(push, 0x00000000); evo_kick(push, sync); - - sync->sem.offset ^= 0x10; - sync->sem.value++; return 0; } @@ -1387,7 +1401,8 @@ nv50_crtc_create(struct drm_device *dev, struct nouveau_object *core, int index) if (ret) goto out; - head->sync.sem.offset = EVO_SYNC(1 + index, 0x00); + head->sync.addr = EVO_FLIP_SEM0(index); + head->sync.data = 0x00000000; /* allocate overlay resources */ ret = nv50_pioc_create(disp->core, NV50_DISP_OIMM_CLASS, index, @@ -2120,15 +2135,23 @@ nv50_display_fini(struct drm_device *dev) int nv50_display_init(struct drm_device *dev) { - u32 *push = evo_wait(nv50_mast(dev), 32); - if (push) { - evo_mthd(push, 0x0088, 1); - evo_data(push, NvEvoSync); - evo_kick(push, nv50_mast(dev)); - return 0; + struct nv50_disp *disp = nv50_disp(dev); + struct drm_crtc *crtc; + u32 *push; + + push = evo_wait(nv50_mast(dev), 32); + if (!push) + return -EBUSY; + + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { + struct nv50_sync *sync = nv50_sync(crtc); + nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data); } - return -EBUSY; + evo_mthd(push, 0x0088, 1); + evo_data(push, NvEvoSync); + evo_kick(push, nv50_mast(dev)); + return 0; } void -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 7f78e0351394052e1a6293e175825eb5c7869507 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Sat, 2 Mar 2013 19:39:14 -0800 Subject: fs: Limit sys_mount to only request filesystem modules. Modify the request_module to prefix the file system type with "fs-" and add aliases to all of the filesystems that can be built as modules to match. A common practice is to build all of the kernel code and leave code that is not commonly needed as modules, with the result that many users are exposed to any bug anywhere in the kernel. Looking for filesystems with a fs- prefix limits the pool of possible modules that can be loaded by mount to just filesystems trivially making things safer with no real cost. Using aliases means user space can control the policy of which filesystem modules are auto-loaded by editing /etc/modprobe.d/*.conf with blacklist and alias directives. Allowing simple, safe, well understood work-arounds to known problematic software. This also addresses a rare but unfortunate problem where the filesystem name is not the same as it's module name and module auto-loading would not work. While writing this patch I saw a handful of such cases. The most significant being autofs that lives in the module autofs4. This is relevant to user namespaces because we can reach the request module in get_fs_type() without having any special permissions, and people get uncomfortable when a user specified string (in this case the filesystem type) goes all of the way to request_module. After having looked at this issue I don't think there is any particular reason to perform any filtering or permission checks beyond making it clear in the module request that we want a filesystem module. The common pattern in the kernel is to call request_module() without regards to the users permissions. In general all a filesystem module does once loaded is call register_filesystem() and go to sleep. Which means there is not much attack surface exposed by loading a filesytem module unless the filesystem is mounted. In a user namespace filesystems are not mounted unless .fs_flags = FS_USERNS_MOUNT, which most filesystems do not set today. Acked-by: Serge Hallyn Acked-by: Kees Cook Reported-by: Kees Cook Signed-off-by: "Eric W. Biederman" --- arch/ia64/kernel/perfmon.c | 1 + arch/powerpc/platforms/cell/spufs/inode.c | 1 + arch/s390/hypfs/inode.c | 1 + drivers/firmware/efivars.c | 1 + drivers/infiniband/hw/ipath/ipath_fs.c | 1 + drivers/infiniband/hw/qib/qib_fs.c | 1 + drivers/misc/ibmasm/ibmasmfs.c | 1 + drivers/mtd/mtdchar.c | 1 + drivers/oprofile/oprofilefs.c | 1 + drivers/staging/ccg/f_fs.c | 1 + drivers/usb/gadget/f_fs.c | 1 + drivers/usb/gadget/inode.c | 1 + drivers/xen/xenfs/super.c | 1 + fs/9p/vfs_super.c | 1 + fs/adfs/super.c | 1 + fs/affs/super.c | 1 + fs/afs/super.c | 1 + fs/autofs4/init.c | 1 + fs/befs/linuxvfs.c | 1 + fs/bfs/inode.c | 1 + fs/binfmt_misc.c | 1 + fs/btrfs/super.c | 1 + fs/ceph/super.c | 1 + fs/coda/inode.c | 1 + fs/configfs/mount.c | 1 + fs/cramfs/inode.c | 1 + fs/debugfs/inode.c | 1 + fs/devpts/inode.c | 1 + fs/ecryptfs/main.c | 1 + fs/efs/super.c | 1 + fs/exofs/super.c | 1 + fs/ext2/super.c | 1 + fs/ext3/super.c | 1 + fs/ext4/super.c | 5 +++-- fs/f2fs/super.c | 1 + fs/fat/namei_msdos.c | 1 + fs/fat/namei_vfat.c | 1 + fs/filesystems.c | 2 +- fs/freevxfs/vxfs_super.c | 2 +- fs/fuse/control.c | 1 + fs/fuse/inode.c | 2 ++ fs/gfs2/ops_fstype.c | 4 +++- fs/hfs/super.c | 1 + fs/hfsplus/super.c | 1 + fs/hppfs/hppfs.c | 1 + fs/hugetlbfs/inode.c | 1 + fs/isofs/inode.c | 3 +-- fs/jffs2/super.c | 1 + fs/jfs/super.c | 1 + fs/logfs/super.c | 1 + fs/minix/inode.c | 1 + fs/ncpfs/inode.c | 1 + fs/nfs/super.c | 3 ++- fs/nfsd/nfsctl.c | 1 + fs/nilfs2/super.c | 1 + fs/ntfs/super.c | 1 + fs/ocfs2/dlmfs/dlmfs.c | 1 + fs/omfs/inode.c | 1 + fs/openpromfs/inode.c | 1 + fs/qnx4/inode.c | 1 + fs/qnx6/inode.c | 1 + fs/reiserfs/super.c | 1 + fs/romfs/super.c | 1 + fs/sysv/super.c | 3 ++- fs/ubifs/super.c | 1 + fs/ufs/super.c | 1 + fs/xfs/xfs_super.c | 1 + include/linux/fs.h | 2 ++ net/sunrpc/rpc_pipe.c | 4 +--- 69 files changed, 77 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 433f5e8a2cd1..2eda28414abb 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -619,6 +619,7 @@ static struct file_system_type pfm_fs_type = { .mount = pfmfs_mount, .kill_sb = kill_anon_super, }; +MODULE_ALIAS_FS("pfmfs"); DEFINE_PER_CPU(unsigned long, pfm_syst_info); DEFINE_PER_CPU(struct task_struct *, pmu_owner); diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 863184b182f4..3f3bb4cdbbec 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -749,6 +749,7 @@ static struct file_system_type spufs_type = { .mount = spufs_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("spufs"); static int __init spufs_init(void) { diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c index 8538015ed4a0..5f7d7ba2874c 100644 --- a/arch/s390/hypfs/inode.c +++ b/arch/s390/hypfs/inode.c @@ -456,6 +456,7 @@ static struct file_system_type hypfs_type = { .mount = hypfs_mount, .kill_sb = hypfs_kill_super }; +MODULE_ALIAS_FS("s390_hypfs"); static const struct super_operations hypfs_s_ops = { .statfs = simple_statfs, diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 7320bf891706..3edade07b249 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -1234,6 +1234,7 @@ static struct file_system_type efivarfs_type = { .mount = efivarfs_mount, .kill_sb = efivarfs_kill_sb, }; +MODULE_ALIAS_FS("efivarfs"); /* * Handle negative dentry. diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index a479375a8fd8..e0c404bdc4a8 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c @@ -410,6 +410,7 @@ static struct file_system_type ipathfs_fs_type = { .mount = ipathfs_mount, .kill_sb = ipathfs_kill_super, }; +MODULE_ALIAS_FS("ipathfs"); int __init ipath_init_ipathfs(void) { diff --git a/drivers/infiniband/hw/qib/qib_fs.c b/drivers/infiniband/hw/qib/qib_fs.c index 644bd6f6467c..f247fc6e6182 100644 --- a/drivers/infiniband/hw/qib/qib_fs.c +++ b/drivers/infiniband/hw/qib/qib_fs.c @@ -604,6 +604,7 @@ static struct file_system_type qibfs_fs_type = { .mount = qibfs_mount, .kill_sb = qibfs_kill_super, }; +MODULE_ALIAS_FS("ipathfs"); int __init qib_init_qibfs(void) { diff --git a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c index 6673e578b3e9..ce5b75616b45 100644 --- a/drivers/misc/ibmasm/ibmasmfs.c +++ b/drivers/misc/ibmasm/ibmasmfs.c @@ -110,6 +110,7 @@ static struct file_system_type ibmasmfs_type = { .mount = ibmasmfs_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("ibmasmfs"); static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent) { diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 82c06165d3d2..92ab30ab00dc 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -1238,6 +1238,7 @@ static struct file_system_type mtd_inodefs_type = { .mount = mtd_inodefs_mount, .kill_sb = kill_anon_super, }; +MODULE_ALIAS_FS("mtd_inodefs"); static int __init init_mtdchar(void) { diff --git a/drivers/oprofile/oprofilefs.c b/drivers/oprofile/oprofilefs.c index 445ffda715ad..7c12d9c2b230 100644 --- a/drivers/oprofile/oprofilefs.c +++ b/drivers/oprofile/oprofilefs.c @@ -276,6 +276,7 @@ static struct file_system_type oprofilefs_type = { .mount = oprofilefs_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("oprofilefs"); int __init oprofilefs_register(void) diff --git a/drivers/staging/ccg/f_fs.c b/drivers/staging/ccg/f_fs.c index 8adc79d1b402..f6373dade7fb 100644 --- a/drivers/staging/ccg/f_fs.c +++ b/drivers/staging/ccg/f_fs.c @@ -1223,6 +1223,7 @@ static struct file_system_type ffs_fs_type = { .mount = ffs_fs_mount, .kill_sb = ffs_fs_kill_sb, }; +MODULE_ALIAS_FS("functionfs"); /* Driver's main init/cleanup functions *************************************/ diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index 38388d7844fc..c377ff84bf2c 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c @@ -1235,6 +1235,7 @@ static struct file_system_type ffs_fs_type = { .mount = ffs_fs_mount, .kill_sb = ffs_fs_kill_sb, }; +MODULE_ALIAS_FS("functionfs"); /* Driver's main init/cleanup functions *************************************/ diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 8ac840f25ba9..e2b2e9cf254a 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c @@ -2105,6 +2105,7 @@ static struct file_system_type gadgetfs_type = { .mount = gadgetfs_mount, .kill_sb = gadgetfs_kill_sb, }; +MODULE_ALIAS_FS("gadgetfs"); /*----------------------------------------------------------------------*/ diff --git a/drivers/xen/xenfs/super.c b/drivers/xen/xenfs/super.c index ec0abb6df3c3..71679875f056 100644 --- a/drivers/xen/xenfs/super.c +++ b/drivers/xen/xenfs/super.c @@ -75,6 +75,7 @@ static struct file_system_type xenfs_type = { .mount = xenfs_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("xenfs"); static int __init xenfs_init(void) { diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c index 91dad63e5a2d..2756dcd5de6e 100644 --- a/fs/9p/vfs_super.c +++ b/fs/9p/vfs_super.c @@ -365,3 +365,4 @@ struct file_system_type v9fs_fs_type = { .owner = THIS_MODULE, .fs_flags = FS_RENAME_DOES_D_MOVE, }; +MODULE_ALIAS_FS("9p"); diff --git a/fs/adfs/super.c b/fs/adfs/super.c index d57122935793..0ff4bae2c2a2 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c @@ -524,6 +524,7 @@ static struct file_system_type adfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("adfs"); static int __init init_adfs_fs(void) { diff --git a/fs/affs/super.c b/fs/affs/super.c index b84dc7352502..45161a832bbc 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c @@ -622,6 +622,7 @@ static struct file_system_type affs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("affs"); static int __init init_affs_fs(void) { diff --git a/fs/afs/super.c b/fs/afs/super.c index 7c31ec399575..c4861557e385 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c @@ -45,6 +45,7 @@ struct file_system_type afs_fs_type = { .kill_sb = afs_kill_super, .fs_flags = 0, }; +MODULE_ALIAS_FS("afs"); static const struct super_operations afs_super_ops = { .statfs = afs_statfs, diff --git a/fs/autofs4/init.c b/fs/autofs4/init.c index cddc74b9cdb2..b3db517e89ec 100644 --- a/fs/autofs4/init.c +++ b/fs/autofs4/init.c @@ -26,6 +26,7 @@ static struct file_system_type autofs_fs_type = { .mount = autofs_mount, .kill_sb = autofs4_kill_sb, }; +MODULE_ALIAS_FS("autofs"); static int __init init_autofs4_fs(void) { diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index c8f4e25eb9e2..8615ee89ab55 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c @@ -951,6 +951,7 @@ static struct file_system_type befs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("befs"); static int __init init_befs_fs(void) diff --git a/fs/bfs/inode.c b/fs/bfs/inode.c index 737aaa3f7090..5e376bb93419 100644 --- a/fs/bfs/inode.c +++ b/fs/bfs/inode.c @@ -473,6 +473,7 @@ static struct file_system_type bfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("bfs"); static int __init init_bfs_fs(void) { diff --git a/fs/binfmt_misc.c b/fs/binfmt_misc.c index fecbbf3f8ff2..751df5e4f61a 100644 --- a/fs/binfmt_misc.c +++ b/fs/binfmt_misc.c @@ -720,6 +720,7 @@ static struct file_system_type bm_fs_type = { .mount = bm_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("binfmt_misc"); static int __init init_misc_binfmt(void) { diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 68a29a1ea068..f6b88595f858 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -1558,6 +1558,7 @@ static struct file_system_type btrfs_fs_type = { .kill_sb = btrfs_kill_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("btrfs"); /* * used by btrfsctl to scan devices when no FS is mounted diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 9fe17c6c2876..6ddc0bca56b2 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -952,6 +952,7 @@ static struct file_system_type ceph_fs_type = { .kill_sb = ceph_kill_sb, .fs_flags = FS_RENAME_DOES_D_MOVE, }; +MODULE_ALIAS_FS("ceph"); #define _STRINGIFY(x) #x #define STRINGIFY(x) _STRINGIFY(x) diff --git a/fs/coda/inode.c b/fs/coda/inode.c index dada9d0abede..4dcc0d81a7aa 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -329,4 +329,5 @@ struct file_system_type coda_fs_type = { .kill_sb = kill_anon_super, .fs_flags = FS_BINARY_MOUNTDATA, }; +MODULE_ALIAS_FS("coda"); diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c index aee0a7ebbd8e..7f26c3cf75ae 100644 --- a/fs/configfs/mount.c +++ b/fs/configfs/mount.c @@ -114,6 +114,7 @@ static struct file_system_type configfs_fs_type = { .mount = configfs_do_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("configfs"); struct dentry *configfs_pin_fs(void) { diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index 3ceb9ec976e1..35b1c7bd18b7 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c @@ -573,6 +573,7 @@ static struct file_system_type cramfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("cramfs"); static int __init init_cramfs_fs(void) { diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 0c4f80b447fb..4888cb3fdef7 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -299,6 +299,7 @@ static struct file_system_type debug_fs_type = { .mount = debug_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("debugfs"); static struct dentry *__create_file(const char *name, umode_t mode, struct dentry *parent, void *data, diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index 073d30b9d1ac..79b662985efe 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -510,6 +510,7 @@ static struct file_system_type devpts_fs_type = { .fs_flags = FS_USERNS_MOUNT | FS_USERNS_DEV_MOUNT, #endif }; +MODULE_ALIAS_FS("devpts"); /* * The normal naming convention is simply /dev/pts/; this conforms diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 4e0886c9e5c4..e924cf45aad9 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c @@ -629,6 +629,7 @@ static struct file_system_type ecryptfs_fs_type = { .kill_sb = ecryptfs_kill_block_super, .fs_flags = 0 }; +MODULE_ALIAS_FS("ecryptfs"); /** * inode_info_init_once diff --git a/fs/efs/super.c b/fs/efs/super.c index 2002431ef9a0..c6f57a74a559 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -33,6 +33,7 @@ static struct file_system_type efs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("efs"); static struct pt_types sgi_pt_types[] = { {0x00, "SGI vh"}, diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 5e59280d42d7..9d9763328734 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c @@ -1010,6 +1010,7 @@ static struct file_system_type exofs_type = { .mount = exofs_mount, .kill_sb = generic_shutdown_super, }; +MODULE_ALIAS_FS("exofs"); static int __init init_exofs(void) { diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 7f68c8114026..288534920fe5 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -1536,6 +1536,7 @@ static struct file_system_type ext2_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ext2"); static int __init init_ext2_fs(void) { diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 5546ca225ffe..1d6e2ed85322 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -3068,6 +3068,7 @@ static struct file_system_type ext3_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ext3"); static int __init init_ext3_fs(void) { diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 5e6c87836193..34e855219231 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -90,6 +90,7 @@ static struct file_system_type ext2_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ext2"); #define IS_EXT2_SB(sb) ((sb)->s_bdev->bd_holder == &ext2_fs_type) #else #define IS_EXT2_SB(sb) (0) @@ -104,6 +105,7 @@ static struct file_system_type ext3_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ext3"); #define IS_EXT3_SB(sb) ((sb)->s_bdev->bd_holder == &ext3_fs_type) #else #define IS_EXT3_SB(sb) (0) @@ -5152,7 +5154,6 @@ static inline int ext2_feature_set_ok(struct super_block *sb) return 0; return 1; } -MODULE_ALIAS("ext2"); #else static inline void register_as_ext2(void) { } static inline void unregister_as_ext2(void) { } @@ -5185,7 +5186,6 @@ static inline int ext3_feature_set_ok(struct super_block *sb) return 0; return 1; } -MODULE_ALIAS("ext3"); #else static inline void register_as_ext3(void) { } static inline void unregister_as_ext3(void) { } @@ -5199,6 +5199,7 @@ static struct file_system_type ext4_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ext4"); static int __init ext4_init_feat_adverts(void) { diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 8c117649a035..fea6e582a2ed 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -687,6 +687,7 @@ static struct file_system_type f2fs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("f2fs"); static int __init init_inodecache(void) { diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index e2cfda94a28d..081b759cff83 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c @@ -668,6 +668,7 @@ static struct file_system_type msdos_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("msdos"); static int __init init_msdos_fs(void) { diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index ac959d655e7d..2da952036a3d 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1073,6 +1073,7 @@ static struct file_system_type vfat_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("vfat"); static int __init init_vfat_fs(void) { diff --git a/fs/filesystems.c b/fs/filesystems.c index da165f6adcbf..92567d95ba6a 100644 --- a/fs/filesystems.c +++ b/fs/filesystems.c @@ -273,7 +273,7 @@ struct file_system_type *get_fs_type(const char *name) int len = dot ? dot - name : strlen(name); fs = __get_fs_type(name, len); - if (!fs && (request_module("%.*s", len, name) == 0)) + if (!fs && (request_module("fs-%.*s", len, name) == 0)) fs = __get_fs_type(name, len); if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) { diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index fed2c8afb3a9..455074308069 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -52,7 +52,6 @@ MODULE_AUTHOR("Christoph Hellwig"); MODULE_DESCRIPTION("Veritas Filesystem (VxFS) driver"); MODULE_LICENSE("Dual BSD/GPL"); -MODULE_ALIAS("vxfs"); /* makes mount -t vxfs autoload the module */ static void vxfs_put_super(struct super_block *); @@ -258,6 +257,7 @@ static struct file_system_type vxfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("vxfs"); /* makes mount -t vxfs autoload the module */ static int __init vxfs_init(void) diff --git a/fs/fuse/control.c b/fs/fuse/control.c index b7978b9f75ef..a0b0855d00a9 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c @@ -341,6 +341,7 @@ static struct file_system_type fuse_ctl_fs_type = { .mount = fuse_ctl_mount, .kill_sb = fuse_ctl_kill_sb, }; +MODULE_ALIAS_FS("fusectl"); int __init fuse_ctl_init(void) { diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index df00993ed108..137185c3884f 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1117,6 +1117,7 @@ static struct file_system_type fuse_fs_type = { .mount = fuse_mount, .kill_sb = fuse_kill_sb_anon, }; +MODULE_ALIAS_FS("fuse"); #ifdef CONFIG_BLOCK static struct dentry *fuse_mount_blk(struct file_system_type *fs_type, @@ -1146,6 +1147,7 @@ static struct file_system_type fuseblk_fs_type = { .kill_sb = fuse_kill_sb_blk, .fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE, }; +MODULE_ALIAS_FS("fuseblk"); static inline int register_fuseblk(void) { diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 1b612be4b873..60ede2a0f43f 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -1425,6 +1426,7 @@ struct file_system_type gfs2_fs_type = { .kill_sb = gfs2_kill_sb, .owner = THIS_MODULE, }; +MODULE_ALIAS_FS("gfs2"); struct file_system_type gfs2meta_fs_type = { .name = "gfs2meta", @@ -1432,4 +1434,4 @@ struct file_system_type gfs2meta_fs_type = { .mount = gfs2_mount_meta, .owner = THIS_MODULE, }; - +MODULE_ALIAS_FS("gfs2meta"); diff --git a/fs/hfs/super.c b/fs/hfs/super.c index e93ddaadfd1e..bbaaa8a4ee64 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c @@ -466,6 +466,7 @@ static struct file_system_type hfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("hfs"); static void hfs_init_once(void *p) { diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 974c26f96fae..7b87284e46dc 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c @@ -654,6 +654,7 @@ static struct file_system_type hfsplus_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("hfsplus"); static void hfsplus_init_once(void *p) { diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 74f55703be49..126d3c2e2dee 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c @@ -748,6 +748,7 @@ static struct file_system_type hppfs_type = { .kill_sb = kill_anon_super, .fs_flags = 0, }; +MODULE_ALIAS_FS("hppfs"); static int __init init_hppfs(void) { diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 7f94e0cbc69c..84e3d856e91d 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -896,6 +896,7 @@ static struct file_system_type hugetlbfs_fs_type = { .mount = hugetlbfs_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("hugetlbfs"); static struct vfsmount *hugetlbfs_vfsmount[HUGE_MAX_HSTATE]; diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 67ce52507d7d..a67f16e846a2 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c @@ -1556,6 +1556,7 @@ static struct file_system_type iso9660_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("iso9660"); static int __init init_iso9660_fs(void) { @@ -1593,5 +1594,3 @@ static void __exit exit_iso9660_fs(void) module_init(init_iso9660_fs) module_exit(exit_iso9660_fs) MODULE_LICENSE("GPL"); -/* Actual filesystem name is iso9660, as requested in filesystems.c */ -MODULE_ALIAS("iso9660"); diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index d3d8799e2187..0defb1cc2a35 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c @@ -356,6 +356,7 @@ static struct file_system_type jffs2_fs_type = { .mount = jffs2_mount, .kill_sb = jffs2_kill_sb, }; +MODULE_ALIAS_FS("jffs2"); static int __init init_jffs2_fs(void) { diff --git a/fs/jfs/super.c b/fs/jfs/super.c index 060ba638becb..2003e830ed1c 100644 --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -833,6 +833,7 @@ static struct file_system_type jfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("jfs"); static void init_once(void *foo) { diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 345c24b8a6f8..54360293bcb5 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c @@ -608,6 +608,7 @@ static struct file_system_type logfs_fs_type = { .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("logfs"); static int __init logfs_init(void) { diff --git a/fs/minix/inode.c b/fs/minix/inode.c index 99541cceb584..df122496f328 100644 --- a/fs/minix/inode.c +++ b/fs/minix/inode.c @@ -660,6 +660,7 @@ static struct file_system_type minix_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("minix"); static int __init init_minix_fs(void) { diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index 7dafd6899a62..26910c8154da 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c @@ -1051,6 +1051,7 @@ static struct file_system_type ncp_fs_type = { .kill_sb = kill_anon_super, .fs_flags = FS_BINARY_MOUNTDATA, }; +MODULE_ALIAS_FS("ncpfs"); static int __init init_ncp_fs(void) { diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 17b32b722457..95cdcb208dfb 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -294,6 +294,7 @@ struct file_system_type nfs_fs_type = { .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, }; +MODULE_ALIAS_FS("nfs"); EXPORT_SYMBOL_GPL(nfs_fs_type); struct file_system_type nfs_xdev_fs_type = { @@ -333,6 +334,7 @@ struct file_system_type nfs4_fs_type = { .kill_sb = nfs_kill_super, .fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA, }; +MODULE_ALIAS_FS("nfs4"); EXPORT_SYMBOL_GPL(nfs4_fs_type); static int __init register_nfs4_fs(void) @@ -2717,6 +2719,5 @@ module_param(send_implementation_id, ushort, 0644); MODULE_PARM_DESC(send_implementation_id, "Send implementation ID with NFSv4.1 exchange_id"); MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string"); -MODULE_ALIAS("nfs4"); #endif /* CONFIG_NFS_V4 */ diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 13a21c8fca49..f33455b4d957 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -1090,6 +1090,7 @@ static struct file_system_type nfsd_fs_type = { .mount = nfsd_mount, .kill_sb = nfsd_umount, }; +MODULE_ALIAS_FS("nfsd"); #ifdef CONFIG_PROC_FS static int create_proc_exports_entry(void) diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 3c991dc84f2f..c7d1f9f18b09 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1361,6 +1361,7 @@ struct file_system_type nilfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("nilfs2"); static void nilfs_inode_init_once(void *obj) { diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 4a8289f8b16c..82650d52d916 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -3079,6 +3079,7 @@ static struct file_system_type ntfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ntfs"); /* Stable names for the slab caches. */ static const char ntfs_index_ctx_cache_name[] = "ntfs_index_ctx_cache"; diff --git a/fs/ocfs2/dlmfs/dlmfs.c b/fs/ocfs2/dlmfs/dlmfs.c index 4c5fc8d77dc2..12bafb7265ce 100644 --- a/fs/ocfs2/dlmfs/dlmfs.c +++ b/fs/ocfs2/dlmfs/dlmfs.c @@ -640,6 +640,7 @@ static struct file_system_type dlmfs_fs_type = { .mount = dlmfs_mount, .kill_sb = kill_litter_super, }; +MODULE_ALIAS_FS("ocfs2_dlmfs"); static int __init init_dlmfs_fs(void) { diff --git a/fs/omfs/inode.c b/fs/omfs/inode.c index 25d715c7c87a..d8b0afde2179 100644 --- a/fs/omfs/inode.c +++ b/fs/omfs/inode.c @@ -572,6 +572,7 @@ static struct file_system_type omfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("omfs"); static int __init init_omfs_fs(void) { diff --git a/fs/openpromfs/inode.c b/fs/openpromfs/inode.c index ae47fa7efb9d..75885ffde44e 100644 --- a/fs/openpromfs/inode.c +++ b/fs/openpromfs/inode.c @@ -432,6 +432,7 @@ static struct file_system_type openprom_fs_type = { .mount = openprom_mount, .kill_sb = kill_anon_super, }; +MODULE_ALIAS_FS("openpromfs"); static void op_inode_init_once(void *data) { diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 43098bb5723a..2e8caa62da78 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -412,6 +412,7 @@ static struct file_system_type qnx4_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("qnx4"); static int __init init_qnx4_fs(void) { diff --git a/fs/qnx6/inode.c b/fs/qnx6/inode.c index 57199a52a351..8d941edfefa1 100644 --- a/fs/qnx6/inode.c +++ b/fs/qnx6/inode.c @@ -672,6 +672,7 @@ static struct file_system_type qnx6_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("qnx6"); static int __init init_qnx6_fs(void) { diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 418bdc3a57da..194113b1b11b 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2434,6 +2434,7 @@ struct file_system_type reiserfs_fs_type = { .kill_sb = reiserfs_kill_sb, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("reiserfs"); MODULE_DESCRIPTION("ReiserFS journaled filesystem"); MODULE_AUTHOR("Hans Reiser "); diff --git a/fs/romfs/super.c b/fs/romfs/super.c index 7e8d3a80bdab..15cbc41ee365 100644 --- a/fs/romfs/super.c +++ b/fs/romfs/super.c @@ -599,6 +599,7 @@ static struct file_system_type romfs_fs_type = { .kill_sb = romfs_kill_sb, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("romfs"); /* * inode storage initialiser diff --git a/fs/sysv/super.c b/fs/sysv/super.c index a38e87bdd78d..a39938b1feea 100644 --- a/fs/sysv/super.c +++ b/fs/sysv/super.c @@ -545,6 +545,7 @@ static struct file_system_type sysv_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("sysv"); static struct file_system_type v7_fs_type = { .owner = THIS_MODULE, @@ -553,6 +554,7 @@ static struct file_system_type v7_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("v7"); static int __init init_sysv_fs(void) { @@ -586,5 +588,4 @@ static void __exit exit_sysv_fs(void) module_init(init_sysv_fs) module_exit(exit_sysv_fs) -MODULE_ALIAS("v7"); MODULE_LICENSE("GPL"); diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index ddc0f6ae65e9..ac838b844936 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c @@ -2174,6 +2174,7 @@ static struct file_system_type ubifs_fs_type = { .mount = ubifs_mount, .kill_sb = kill_ubifs_super, }; +MODULE_ALIAS_FS("ubifs"); /* * Inode slab cache constructor. diff --git a/fs/ufs/super.c b/fs/ufs/super.c index dc8e3a861d0f..329f2f53b7ed 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -1500,6 +1500,7 @@ static struct file_system_type ufs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("ufs"); static int __init init_ufs_fs(void) { diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index c407121873b4..ea341cea68cb 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c @@ -1561,6 +1561,7 @@ static struct file_system_type xfs_fs_type = { .kill_sb = kill_block_super, .fs_flags = FS_REQUIRES_DEV, }; +MODULE_ALIAS_FS("xfs"); STATIC int __init xfs_init_zones(void) diff --git a/include/linux/fs.h b/include/linux/fs.h index 74a907b8b950..2c28271ab9d4 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1825,6 +1825,8 @@ struct file_system_type { struct lock_class_key i_mutex_dir_key; }; +#define MODULE_ALIAS_FS(NAME) MODULE_ALIAS("fs-" NAME) + extern struct dentry *mount_ns(struct file_system_type *fs_type, int flags, void *data, int (*fill_super)(struct super_block *, void *, int)); extern struct dentry *mount_bdev(struct file_system_type *fs_type, diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index 7b9b40224a27..a0f48a51e14e 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c @@ -1174,6 +1174,7 @@ static struct file_system_type rpc_pipe_fs_type = { .mount = rpc_mount, .kill_sb = rpc_kill_sb, }; +MODULE_ALIAS_FS("rpc_pipefs"); static void init_once(void *foo) @@ -1218,6 +1219,3 @@ void unregister_rpc_pipefs(void) kmem_cache_destroy(rpc_inode_cachep); unregister_filesystem(&rpc_pipe_fs_type); } - -/* Make 'mount -t rpc_pipefs ...' autoload this module. */ -MODULE_ALIAS("rpc_pipefs"); -- cgit v1.2.3 From dbd712c2272764a536e29ad6841dba74989a39d9 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 21 Feb 2013 09:33:25 -0800 Subject: hwmon: (pmbus/ltc2978) Fix peak attribute handling Peak attributes were not initialized and cleared correctly. Also, temp2_max is only supported on page 0 and thus does not need to be an array. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.2+ Acked-by: Jean Delvare --- drivers/hwmon/pmbus/ltc2978.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index 9652a2c92a24..cc29a7e57bd7 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -62,7 +62,7 @@ struct ltc2978_data { int temp_min, temp_max; int vout_min[8], vout_max[8]; int iout_max[2]; - int temp2_max[2]; + int temp2_max; struct pmbus_driver_info info; }; @@ -204,10 +204,9 @@ static int ltc3880_read_word_data(struct i2c_client *client, int page, int reg) ret = pmbus_read_word_data(client, page, LTC3880_MFR_TEMPERATURE2_PEAK); if (ret >= 0) { - if (lin11_to_val(ret) - > lin11_to_val(data->temp2_max[page])) - data->temp2_max[page] = ret; - ret = data->temp2_max[page]; + if (lin11_to_val(ret) > lin11_to_val(data->temp2_max)) + data->temp2_max = ret; + ret = data->temp2_max; } break; case PMBUS_VIRT_READ_VIN_MIN: @@ -248,11 +247,11 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, switch (reg) { case PMBUS_VIRT_RESET_IOUT_HISTORY: - data->iout_max[page] = 0x7fff; + data->iout_max[page] = 0x7c00; ret = ltc2978_clear_peaks(client, page, data->id); break; case PMBUS_VIRT_RESET_TEMP2_HISTORY: - data->temp2_max[page] = 0x7fff; + data->temp2_max = 0x7c00; ret = ltc2978_clear_peaks(client, page, data->id); break; case PMBUS_VIRT_RESET_VOUT_HISTORY: @@ -262,12 +261,12 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, break; case PMBUS_VIRT_RESET_VIN_HISTORY: data->vin_min = 0x7bff; - data->vin_max = 0; + data->vin_max = 0x7c00; ret = ltc2978_clear_peaks(client, page, data->id); break; case PMBUS_VIRT_RESET_TEMP_HISTORY: data->temp_min = 0x7bff; - data->temp_max = 0x7fff; + data->temp_max = 0x7c00; ret = ltc2978_clear_peaks(client, page, data->id); break; default: @@ -321,10 +320,11 @@ static int ltc2978_probe(struct i2c_client *client, info = &data->info; info->write_word_data = ltc2978_write_word_data; - data->vout_min[0] = 0xffff; data->vin_min = 0x7bff; + data->vin_max = 0x7c00; data->temp_min = 0x7bff; - data->temp_max = 0x7fff; + data->temp_max = 0x7c00; + data->temp2_max = 0x7c00; switch (id->driver_data) { case ltc2978: @@ -336,7 +336,6 @@ static int ltc2978_probe(struct i2c_client *client, for (i = 1; i < 8; i++) { info->func[i] = PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT; - data->vout_min[i] = 0xffff; } break; case ltc3880: @@ -352,11 +351,14 @@ static int ltc2978_probe(struct i2c_client *client, | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT | PMBUS_HAVE_POUT | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; - data->vout_min[1] = 0xffff; + data->iout_max[0] = 0x7c00; + data->iout_max[1] = 0x7c00; break; default: return -ENODEV; } + for (i = 0; i < info->pages; i++) + data->vout_min[i] = 0xffff; return pmbus_do_probe(client, id, info); } -- cgit v1.2.3 From f366fccd0809f13ba20d64cae3c83f7338c88af7 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 21 Feb 2013 10:49:40 -0800 Subject: hwmon: (pmbus/ltc2978) Use detected chip ID to select supported functionality We read the chip ID from the chip, use it to determine if the chip ID provided to the driver is correct, and report it if wrong. We should also use the correct chip ID to select supported functionality. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.2+ Acked-by: Jean Delvare --- drivers/hwmon/pmbus/ltc2978.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index cc29a7e57bd7..a58de38e23d8 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -326,7 +326,7 @@ static int ltc2978_probe(struct i2c_client *client, data->temp_max = 0x7c00; data->temp2_max = 0x7c00; - switch (id->driver_data) { + switch (data->id) { case ltc2978: info->read_word_data = ltc2978_read_word_data; info->pages = 8; -- cgit v1.2.3 From 3e78080f81481aa8340374d5a37ae033c1cf4272 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Mar 2013 15:33:30 +0800 Subject: hwmon: (sht15) Check return value of regulator_enable() Not having power is a pretty serious error so check that we are able to enable the supply and error out if we can't. Signed-off-by: Mark Brown Cc: stable@vger.kernel.org #3.8+; 3.0+ will need manual backport Signed-off-by: Guenter Roeck --- drivers/hwmon/sht15.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/sht15.c b/drivers/hwmon/sht15.c index bfe326e896df..2507f902fb7a 100644 --- a/drivers/hwmon/sht15.c +++ b/drivers/hwmon/sht15.c @@ -965,7 +965,13 @@ static int sht15_probe(struct platform_device *pdev) if (voltage) data->supply_uv = voltage; - regulator_enable(data->reg); + ret = regulator_enable(data->reg); + if (ret != 0) { + dev_err(&pdev->dev, + "failed to enable regulator: %d\n", ret); + return ret; + } + /* * Setup a notifier block to update this if another device * causes the voltage to change -- cgit v1.2.3 From d9b4330adec006c2e8907bdcacd9dcc0e8874d18 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 8 Feb 2013 15:14:16 +0200 Subject: usb: dwc3: core: don't forget to free coherent memory commit 3921426 (usb: dwc3: core: move event buffer allocation out of dwc3_core_init()) introduced a memory leak of the coherent memory we use as event buffers on dwc3 driver. If the driver is compiled as a dynamically loadable module and use constantly loads and unloads the driver, we will continue to leak the coherent memory allocated during ->probe() because dwc3_free_event_buffers() is never called during ->remove(). Cc: # v3.7 v3.8 Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/core.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index 999909451e37..ffa6b004a84b 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -583,6 +583,7 @@ static int dwc3_remove(struct platform_device *pdev) break; } + dwc3_free_event_buffers(dwc); dwc3_core_exit(dwc); return 0; -- cgit v1.2.3 From 2c2dc89cc5d68ca161d50011cdcbf8aa830b9498 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Feb 2013 10:31:15 +0200 Subject: usb: dwc3: omap: fix a typo on of_device_id s/matach/match No functional changes Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-omap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 22f337f57219..90171f7ccf8d 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -465,20 +465,20 @@ static int dwc3_omap_remove(struct platform_device *pdev) return 0; } -static const struct of_device_id of_dwc3_matach[] = { +static const struct of_device_id of_dwc3_match[] = { { "ti,dwc3", }, { }, }; -MODULE_DEVICE_TABLE(of, of_dwc3_matach); +MODULE_DEVICE_TABLE(of, of_dwc3_match); static struct platform_driver dwc3_omap_driver = { .probe = dwc3_omap_probe, .remove = dwc3_omap_remove, .driver = { .name = "omap-dwc3", - .of_match_table = of_dwc3_matach, + .of_match_table = of_dwc3_match, }, }; -- cgit v1.2.3 From d82f3e3cd88053836a2dd928b5545873cbdcf7da Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 12 Feb 2013 10:48:55 +0200 Subject: usb: dwc3: glue layers shouldn't know about the core IP remove inclusion of "core.h" from all glue layers as they don't need to know details about the core IP. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/dwc3-exynos.c | 2 -- drivers/usb/dwc3/dwc3-omap.c | 2 -- drivers/usb/dwc3/dwc3-pci.c | 2 -- 3 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c index b50da53e9a52..b082bec7343e 100644 --- a/drivers/usb/dwc3/dwc3-exynos.c +++ b/drivers/usb/dwc3/dwc3-exynos.c @@ -23,8 +23,6 @@ #include #include -#include "core.h" - struct dwc3_exynos { struct platform_device *dwc3; struct platform_device *usb2_phy; diff --git a/drivers/usb/dwc3/dwc3-omap.c b/drivers/usb/dwc3/dwc3-omap.c index 90171f7ccf8d..afa05e3c9cf4 100644 --- a/drivers/usb/dwc3/dwc3-omap.c +++ b/drivers/usb/dwc3/dwc3-omap.c @@ -54,8 +54,6 @@ #include #include -#include "core.h" - /* * All these registers belong to OMAP's Wrapper around the * DesignWare USB3 Core. diff --git a/drivers/usb/dwc3/dwc3-pci.c b/drivers/usb/dwc3/dwc3-pci.c index 7d70f44567d2..e8d77689a322 100644 --- a/drivers/usb/dwc3/dwc3-pci.c +++ b/drivers/usb/dwc3/dwc3-pci.c @@ -45,8 +45,6 @@ #include #include -#include "core.h" - /* FIXME define these in */ #define PCI_VENDOR_ID_SYNOPSYS 0x16c3 #define PCI_DEVICE_ID_SYNOPSYS_HAPSUSB3 0xabcd -- cgit v1.2.3 From e5b29b25f8f88ece53579fa87580bb2973815977 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Fri, 15 Feb 2013 10:45:42 +0200 Subject: usb: dwc3: gadget: remove unnecessary code the params variables on dwc3_gadget_conndone_interrupt() is only memset() to zero but never used in that function, so we can safely drop the variable and memset() call. Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/gadget.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index a04342f6cbfa..82e160e96fca 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -2159,7 +2159,6 @@ static void dwc3_gadget_phy_suspend(struct dwc3 *dwc, u8 speed) static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) { - struct dwc3_gadget_ep_cmd_params params; struct dwc3_ep *dep; int ret; u32 reg; @@ -2167,8 +2166,6 @@ static void dwc3_gadget_conndone_interrupt(struct dwc3 *dwc) dev_vdbg(dwc->dev, "%s\n", __func__); - memset(¶ms, 0x00, sizeof(params)); - reg = dwc3_readl(dwc->regs, DWC3_DSTS); speed = reg & DWC3_DSTS_CONNECTSPD; dwc->speed = speed; -- cgit v1.2.3 From 2b7dc3b1a6cd23cb75ada8505fa80687acd4fa04 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Thu, 24 Jan 2013 17:34:32 +0200 Subject: usb: chipidea: register debugging sysfs on our device Don't register anything non-generic under the gadget's device as we don't really *own* it. Signed-off-by: Felipe Balbi --- drivers/usb/chipidea/udc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c index 2f45bba8561d..f64fbea1cf20 100644 --- a/drivers/usb/chipidea/udc.c +++ b/drivers/usb/chipidea/udc.c @@ -1767,7 +1767,7 @@ static int udc_start(struct ci13xxx *ci) goto put_transceiver; } - retval = dbg_create_files(&ci->gadget.dev); + retval = dbg_create_files(ci->dev); if (retval) goto unreg_device; @@ -1796,7 +1796,7 @@ remove_trans: dev_err(dev, "error = %i\n", retval); remove_dbg: - dbg_remove_files(&ci->gadget.dev); + dbg_remove_files(ci->dev); unreg_device: device_unregister(&ci->gadget.dev); put_transceiver: @@ -1836,7 +1836,7 @@ static void udc_stop(struct ci13xxx *ci) if (ci->global_phy) usb_put_phy(ci->transceiver); } - dbg_remove_files(&ci->gadget.dev); + dbg_remove_files(ci->dev); device_unregister(&ci->gadget.dev); /* my kobject is dynamic, I swear! */ memset(&ci->gadget, 0, sizeof(ci->gadget)); -- cgit v1.2.3 From fe2a4297b40c0ccee0e2276b06fb0afe1fc63da4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 08:49:05 +0200 Subject: usb: gadget: pxa27x: fix gadget->dev registration Whenever ->udc_start() gets called, gadget driver has already being bound to the udc controller, which means that gadget->dev had to be already initialized and added to driver model. This patch fixes pxa27x mistake. Tested-by: Robert Jarzmik Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa27x_udc.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index f7d25795821a..2fc867652ef5 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -1814,11 +1814,6 @@ static int pxa27x_udc_start(struct usb_gadget *g, udc->gadget.dev.driver = &driver->driver; dplus_pullup(udc, 1); - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(udc->dev, "device_add error %d\n", retval); - goto fail; - } if (!IS_ERR_OR_NULL(udc->transceiver)) { retval = otg_set_peripheral(udc->transceiver->otg, &udc->gadget); @@ -1876,7 +1871,6 @@ static int pxa27x_udc_stop(struct usb_gadget *g, udc->driver = NULL; - device_del(&udc->gadget.dev); if (!IS_ERR_OR_NULL(udc->transceiver)) return otg_set_peripheral(udc->transceiver->otg, NULL); @@ -2480,13 +2474,24 @@ static int __init pxa_udc_probe(struct platform_device *pdev) driver_name, udc->irq, retval); 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; pxa_init_debugfs(udc); + return 0; + err_add_udc: + device_unregister(&udc->gadget.dev); +err_dev_add: free_irq(udc->irq, udc); err_irq: iounmap(udc->regs); @@ -2507,6 +2512,7 @@ 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 v1.2.3 From 56aa45adcc5b793369e535a4b7177f1c7314b577 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Wed, 6 Feb 2013 14:20:34 +0530 Subject: usb: gadget: make usb functions to load before gadget driver The current ordering in makefile makes gadget drivers be loaded before usb functions which causes usb_get_function_instance() to fail when gadget modules are statically linked to the kernel binary. Changed the ordering here so that USB functions are loaded before gadget drivers. Note that this is only a temporary solution and a more robust fix is needed in the long run. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/gadget/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 97a13c349cc5..82fb22511356 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -35,6 +35,12 @@ mv_udc-y := mv_udc_core.o obj-$(CONFIG_USB_FUSB300) += fusb300_udc.o obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o +# USB Functions +obj-$(CONFIG_USB_F_ACM) += f_acm.o +f_ss_lb-y := f_loopback.o f_sourcesink.o +obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o +obj-$(CONFIG_USB_U_SERIAL) += u_serial.o + # # USB gadget drivers # @@ -74,9 +80,3 @@ obj-$(CONFIG_USB_G_WEBCAM) += g_webcam.o obj-$(CONFIG_USB_G_NCM) += g_ncm.o obj-$(CONFIG_USB_G_ACM_MS) += g_acm_ms.o obj-$(CONFIG_USB_GADGET_TARGET) += tcm_usb_gadget.o - -# USB Functions -obj-$(CONFIG_USB_F_ACM) += f_acm.o -f_ss_lb-y := f_loopback.o f_sourcesink.o -obj-$(CONFIG_USB_F_SS_LB) += f_ss_lb.o -obj-$(CONFIG_USB_U_SERIAL) += u_serial.o -- cgit v1.2.3 From 7597a49b1e984bfb9930f832af963de1120d30e4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 21:11:50 +0200 Subject: usb: gadget: s3c2410: fix gadget->dev registration Whenever ->udc_start() gets called, gadget driver has already being bound to the udc controller, which means that gadget->dev had to be already initialized and added to driver model. This patch fixes s3c2410 mistake. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index fc07b4381286..940485899efc 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1669,7 +1669,6 @@ static int s3c2410_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { struct s3c2410_udc *udc = to_s3c2410(g) - int retval; dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); @@ -1677,22 +1676,10 @@ static int s3c2410_udc_start(struct usb_gadget *g, udc->driver = driver; udc->gadget.dev.driver = &driver->driver; - /* Bind the driver */ - retval = device_add(&udc->gadget.dev); - if (retval) { - dev_err(&udc->gadget.dev, "Error in device_add() : %d\n", retval); - goto register_error; - } - /* Enable udc */ s3c2410_udc_enable(udc); return 0; - -register_error: - udc->driver = NULL; - udc->gadget.dev.driver = NULL; - return retval; } static int s3c2410_udc_stop(struct usb_gadget *g, @@ -1700,7 +1687,6 @@ static int s3c2410_udc_stop(struct usb_gadget *g, { struct s3c2410_udc *udc = to_s3c2410(g); - device_del(&udc->gadget.dev); udc->driver = NULL; /* Disable udc */ @@ -1842,6 +1828,13 @@ static int s3c2410_udc_probe(struct platform_device *pdev) 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; + } + the_controller = udc; platform_set_drvdata(pdev, udc); @@ -1930,6 +1923,8 @@ 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); @@ -1947,10 +1942,11 @@ static int s3c2410_udc_remove(struct platform_device *pdev) dev_dbg(&pdev->dev, "%s()\n", __func__); - usb_del_gadget_udc(&udc->gadget); if (udc->driver) 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 v1.2.3 From 9992a9979fd463903e1a34b68d609441f36bafd4 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 21:15:41 +0200 Subject: usb: gadget: pxa25x: fix gadget->dev registration Whenever ->udc_start() gets called, gadget driver has already being bound to the udc controller, which means that gadget->dev had to be already initialized and added to driver model. This patch fixes pxa25x mistake. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 2bbcdce942dc..9aa9dd5168d8 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -1266,13 +1266,6 @@ static int pxa25x_udc_start(struct usb_gadget *g, dev->gadget.dev.driver = &driver->driver; dev->pullup = 1; - retval = device_add (&dev->gadget.dev); - if (retval) { - dev->driver = NULL; - dev->gadget.dev.driver = NULL; - return retval; - } - /* ... then enable host detection and ep0; and we're ready * for set_configuration as well as eventual disconnect. */ @@ -1331,7 +1324,6 @@ static int pxa25x_udc_stop(struct usb_gadget*g, dev->gadget.dev.driver = NULL; dev->driver = NULL; - device_del (&dev->gadget.dev); dump_state(dev); return 0; @@ -2146,6 +2138,13 @@ 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; + retval = device_add(&dev->gadget.dev); + if (retval) { + dev->driver = NULL; + dev->gadget.dev.driver = NULL; + goto err_device_add; + } + the_controller = dev; platform_set_drvdata(pdev, dev); @@ -2196,6 +2195,8 @@ 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: @@ -2217,10 +2218,11 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev) { struct pxa25x_udc *dev = platform_get_drvdata(pdev); - usb_del_gadget_udc(&dev->gadget); if (dev->driver) return -EBUSY; + usb_del_gadget_udc(&dev->gadget); + device_unregister(&dev->gadget.dev); dev->pullup = 0; pullup(dev); -- cgit v1.2.3 From bc530a72726d54357ea3a10e82761f203201e5b2 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 21:17:59 +0200 Subject: usb: gadget: imx_udc: fix gadget->dev registration Whenever ->udc_start() gets called, gadget driver has already being bound to the udc controller, which means that gadget->dev had to be already initialized and added to driver model. This patch fixes imx_udc mistake. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/imx_udc.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 8efd7555fa21..5bd930d779b9 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1334,27 +1334,18 @@ static int imx_udc_start(struct usb_gadget *gadget, struct usb_gadget_driver *driver) { struct imx_udc_struct *imx_usb; - int retval; 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; - retval = device_add(&imx_usb->gadget.dev); - if (retval) - goto fail; - D_INI(imx_usb->dev, "<%s> registered gadget driver '%s'\n", __func__, driver->driver.name); imx_udc_enable(imx_usb); return 0; -fail: - imx_usb->driver = NULL; - imx_usb->gadget.dev.driver = NULL; - return retval; } static int imx_udc_stop(struct usb_gadget *gadget, @@ -1370,8 +1361,6 @@ static int imx_udc_stop(struct usb_gadget *gadget, imx_usb->gadget.dev.driver = NULL; imx_usb->driver = NULL; - device_del(&imx_usb->gadget.dev); - D_INI(imx_usb->dev, "<%s> unregistered gadget driver '%s'\n", __func__, driver->driver.name); @@ -1477,6 +1466,10 @@ static int __init imx_udc_probe(struct platform_device *pdev) 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); @@ -1488,9 +1481,11 @@ static int __init imx_udc_probe(struct platform_device *pdev) ret = usb_add_gadget_udc(&pdev->dev, &imx_usb->gadget); if (ret) - goto fail4; + goto fail5; 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); @@ -1514,6 +1509,7 @@ 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 v1.2.3 From 4ea34de7615c1208a08bce3ff75c234cca03c654 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 25 Feb 2013 21:25:04 +0200 Subject: usb: gadget: s3c2410: fix build breakage add missing semicolon to fix compile breakage. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/s3c2410_udc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 940485899efc..08f89652533b 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c @@ -1668,7 +1668,7 @@ static void s3c2410_udc_enable(struct s3c2410_udc *dev) static int s3c2410_udc_start(struct usb_gadget *g, struct usb_gadget_driver *driver) { - struct s3c2410_udc *udc = to_s3c2410(g) + struct s3c2410_udc *udc = to_s3c2410(g); dprintk(DEBUG_NORMAL, "%s() '%s'\n", __func__, driver->driver.name); -- cgit v1.2.3 From a10840c9acbeca7aada3543823fdb59909342d96 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 31 Jan 2013 13:30:40 +0100 Subject: usb: musb: correct Kconfig in order to avoid non compilable selection Currently it is possible to have: USB_MUSB_OMAP2PLUS=m TWL4030_USB=y which would result compile time error due to missing symbols. With this change USB_MUSB_OMAP2PLUS and TWL4030_USB will be in sync. Reported-by: Vincent Stehle Signed-off-by: Peter Ujfalusi Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 45b19e2c60ba..2f7d84af6650 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -9,8 +9,6 @@ config USB_MUSB_HDRC depends on USB && USB_GADGET select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) - select TWL4030_USB if MACH_OMAP_3430SDP - select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA select USB_OTG_UTILS help @@ -51,6 +49,8 @@ config USB_MUSB_TUSB6010 config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" depends on ARCH_OMAP2PLUS + select TWL4030_USB if MACH_OMAP_3430SDP + select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA config USB_MUSB_AM35X tristate "AM35x" -- cgit v1.2.3 From 1dd03d8a510dae402096b194385a1373100450dc Mon Sep 17 00:00:00 2001 From: Marc Kleine-Budde Date: Wed, 27 Feb 2013 15:11:13 +0100 Subject: usb: otg: use try_module_get in all usb_get_phy functions and add missing module_put In patch "5d3c28b usb: otg: add device tree support to otg library" devm_usb_get_phy_by_phandle() was added. It uses try_module_get() to lock the phy driver in memory. The corresponding module_put() is missing in that patch. This patch adds try_module_get() to usb_get_phy() and usb_get_phy_dev(). Further the missing module_put() is added to usb_put_phy(). Tested-by: Steffen Trumtrar Reviewed-by: Kishon Vijay Abraham I Signed-off-by: Marc Kleine-Budde Signed-off-by: Michael Grzeschik Signed-off-by: Felipe Balbi --- drivers/usb/otg/otg.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/otg/otg.c b/drivers/usb/otg/otg.c index e1814397ca3a..2bd03d261a50 100644 --- a/drivers/usb/otg/otg.c +++ b/drivers/usb/otg/otg.c @@ -130,7 +130,7 @@ struct usb_phy *usb_get_phy(enum usb_phy_type type) spin_lock_irqsave(&phy_lock, flags); phy = __usb_find_phy(&phy_list, type); - if (IS_ERR(phy)) { + 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; @@ -228,7 +228,7 @@ struct usb_phy *usb_get_phy_dev(struct device *dev, u8 index) spin_lock_irqsave(&phy_lock, flags); phy = __usb_find_phy_dev(dev, &phy_bind_list, index); - if (IS_ERR(phy)) { + if (IS_ERR(phy) || !try_module_get(phy->dev->driver->owner)) { pr_err("unable to find transceiver\n"); goto err0; } @@ -301,8 +301,12 @@ EXPORT_SYMBOL(devm_usb_put_phy); */ void usb_put_phy(struct usb_phy *x) { - if (x) + if (x) { + struct module *owner = x->dev->driver->owner; + put_device(x->dev); + module_put(owner); + } } EXPORT_SYMBOL(usb_put_phy); -- cgit v1.2.3 From 34dcfb8479ab3c3669561eb9279284cb0eda2572 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Wed, 27 Feb 2013 22:30:24 +0100 Subject: TTY: disable debugging warning We added a warning to flush_to_ldisc to report cases when it is called with a NULL tty. It was for debugging purposes and it lead to a patchset from Peter Hurley. The patchset however did not make it to 3.9, so disable the warning now to not disturb people. We can re-add it when the series is in and we are hunting for another bugs. Reported-by: David Miller Cc: stable # 3.8 Signed-off-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/tty_buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index bb119934e76c..578aa7594b11 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c @@ -425,7 +425,7 @@ static void flush_to_ldisc(struct work_struct *work) struct tty_ldisc *disc; tty = port->itty; - if (WARN_RATELIMIT(tty == NULL, "tty is NULL\n")) + if (tty == NULL) return; disc = tty_ldisc_ref(tty); -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From a40070410329fb704aedf9451732ffb92a3fe39f Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 14:05:41 +0530 Subject: usb: phy: samsung: 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. Reviewed-by: Thierry Reding Signed-off-by: Sachin Kamat Signed-off-by: Felipe Balbi --- drivers/usb/phy/samsung-usbphy.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/samsung-usbphy.c b/drivers/usb/phy/samsung-usbphy.c index 6ea553733832..967101ec15fd 100644 --- a/drivers/usb/phy/samsung-usbphy.c +++ b/drivers/usb/phy/samsung-usbphy.c @@ -787,11 +787,9 @@ static int samsung_usbphy_probe(struct platform_device *pdev) 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; - } + 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) -- cgit v1.2.3 From 862421da0d82a3c35aa89e040a533f76d24c62c4 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 14:05:42 +0530 Subject: usb: phy: omap-usb3: 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. Reviewed-by: Thierry Reding Signed-off-by: Sachin Kamat Cc: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/phy/omap-usb3.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/omap-usb3.c b/drivers/usb/phy/omap-usb3.c index fadc0c2b65bb..a6e60b1e102e 100644 --- a/drivers/usb/phy/omap-usb3.c +++ b/drivers/usb/phy/omap-usb3.c @@ -212,11 +212,9 @@ static int omap_usb3_probe(struct platform_device *pdev) } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); - phy->pll_ctrl_base = devm_request_and_ioremap(&pdev->dev, res); - if (!phy->pll_ctrl_base) { - dev_err(&pdev->dev, "ioremap of pll_ctrl failed\n"); - return -ENOMEM; - } + 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; -- cgit v1.2.3 From 57ae575b8a51fd98c9b0066c6c030d5ccce3d77d Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 14:05:43 +0530 Subject: usb: phy: omap-control-usb: 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. Reviewed-by: Thierry Reding Signed-off-by: Sachin Kamat Cc: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/phy/omap-control-usb.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/phy/omap-control-usb.c b/drivers/usb/phy/omap-control-usb.c index 5323b71c3521..1419ceda9759 100644 --- a/drivers/usb/phy/omap-control-usb.c +++ b/drivers/usb/phy/omap-control-usb.c @@ -219,32 +219,26 @@ static int omap_control_usb_probe(struct platform_device *pdev) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control_dev_conf"); - control_usb->dev_conf = devm_request_and_ioremap(&pdev->dev, res); - if (!control_usb->dev_conf) { - dev_err(&pdev->dev, "Failed to obtain io memory\n"); - return -EADDRNOTAVAIL; - } + 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_request_and_ioremap( + control_usb->otghs_control = devm_ioremap_resource( &pdev->dev, res); - if (!control_usb->otghs_control) { - dev_err(&pdev->dev, "Failed to obtain io memory\n"); - return -EADDRNOTAVAIL; - } + 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_request_and_ioremap( + control_usb->phy_power = devm_ioremap_resource( &pdev->dev, res); - if (!control_usb->phy_power) { - dev_dbg(&pdev->dev, "Failed to obtain io memory\n"); - return -EADDRNOTAVAIL; - } + 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"); -- cgit v1.2.3 From fddedd8334d8b4ac6374894d5eed237d18ce1afb Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Feb 2013 07:43:12 +0300 Subject: usb: gadget: f_uac1: silence an info leak warning Smatch complains that "len" could be larger than the sizeof(value) so we could be copying garbage here. I have changed this to match how things are done in composite_setup(). The call tree looks like: composite_setup() --> f_audio_setup() --> audio_get_intf_req() composite_setup() expects the return value to be set to sizeof(value). Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_uac1.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_uac1.c b/drivers/usb/gadget/f_uac1.c index f570e667a640..fa8ea4ea00c1 100644 --- a/drivers/usb/gadget/f_uac1.c +++ b/drivers/usb/gadget/f_uac1.c @@ -418,6 +418,7 @@ static int audio_get_intf_req(struct usb_function *f, req->context = audio; req->complete = f_audio_complete; + len = min_t(size_t, sizeof(value), len); memcpy(req->buf, &value, len); return len; -- cgit v1.2.3 From 29240e2392786c39007df2f4162f3dc4680f3dec Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Feb 2013 07:44:38 +0300 Subject: usb: gadget: u_uac1: NULL dereference on error path We should return here with an error code instead of continuing. Signed-off-by: Dan Carpenter Signed-off-by: Felipe Balbi --- drivers/usb/gadget/u_uac1.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/u_uac1.c b/drivers/usb/gadget/u_uac1.c index e0c5e88e03ed..c7d460f43390 100644 --- a/drivers/usb/gadget/u_uac1.c +++ b/drivers/usb/gadget/u_uac1.c @@ -240,8 +240,11 @@ static int gaudio_open_snd_dev(struct gaudio *card) snd = &card->playback; snd->filp = filp_open(fn_play, O_WRONLY, 0); if (IS_ERR(snd->filp)) { + int ret = PTR_ERR(snd->filp); + ERROR(card, "No such PCM playback device: %s\n", fn_play); snd->filp = NULL; + return ret; } pcm_file = snd->filp->private_data; snd->substream = pcm_file->substream; -- cgit v1.2.3 From 715c998ff4d1106c3096bc5a48e4196663e6701a Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 28 Feb 2013 08:57:31 +0200 Subject: iwlwifi: mvm: restart the NIC of the cmd queue gets full This situation is clearly an error situation and the only way to recover is to restart the driver / fw. Signed-off-by: Emmanuel Grumbach Reviewed-by: Ilan Peer Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/ops.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c index aa59adf87db3..d0f9c1e0475e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/iwlwifi/mvm/ops.c @@ -624,12 +624,8 @@ static void iwl_mvm_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb) ieee80211_free_txskb(mvm->hw, skb); } -static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) +static void iwl_mvm_nic_restart(struct iwl_mvm *mvm) { - struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); - - iwl_mvm_dump_nic_error_log(mvm); - iwl_abort_notification_waits(&mvm->notif_wait); /* @@ -663,9 +659,21 @@ static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) } } +static void iwl_mvm_nic_error(struct iwl_op_mode *op_mode) +{ + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); + + iwl_mvm_dump_nic_error_log(mvm); + + iwl_mvm_nic_restart(mvm); +} + static void iwl_mvm_cmd_queue_full(struct iwl_op_mode *op_mode) { + struct iwl_mvm *mvm = IWL_OP_MODE_GET_MVM(op_mode); + WARN_ON(1); + iwl_mvm_nic_restart(mvm); } static const struct iwl_op_mode_ops iwl_mvm_ops = { -- cgit v1.2.3 From e07cbb536acb249db5fd63f6884354630ae875ad Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 23:00:27 +0200 Subject: iwlwifi: mvm: Set valid TX antennas value before calib request We must set the valid TX antennas number in the ucode before sending the phy_cfg_cmd and request for calibrations. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index d3d959db03a9..e6d51a9069c9 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -446,6 +446,11 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) ret = iwl_nvm_check_version(mvm->nvm_data, mvm->trans); WARN_ON(ret); + /* Send TX valid antennas before triggering calibrations */ + ret = iwl_send_tx_ant_cfg(mvm, mvm->nvm_data->valid_tx_ant); + if (ret) + goto error; + /* Override the calibrations from TLV and the const of fw */ iwl_set_default_calib_trigger(mvm); -- cgit v1.2.3 From 6221d47cf7a57eb1e2b5b51c65e2edcde369a0d4 Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 15:55:48 +0200 Subject: iwlwifi: mvm: Take the phy_cfg from the TLV value The phy_cfg is given from the TLV value and does not have to be built by us. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index e6d51a9069c9..d3c067e670a8 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -241,20 +241,6 @@ static int iwl_mvm_load_ucode_wait_alive(struct iwl_mvm *mvm, return 0; } -#define IWL_HW_REV_ID_RAINBOW 0x2 -#define IWL_PROJ_TYPE_LHP 0x5 - -static u32 iwl_mvm_build_phy_cfg(struct iwl_mvm *mvm) -{ - struct iwl_nvm_data *data = mvm->nvm_data; - /* Temp calls to static definitions, will be changed to CSR calls */ - u8 hw_rev_id = IWL_HW_REV_ID_RAINBOW; - u8 project_type = IWL_PROJ_TYPE_LHP; - - return data->radio_cfg_dash | (data->radio_cfg_step << 2) | - (hw_rev_id << 4) | ((project_type & 0x7f) << 6) | - (data->valid_tx_ant << 16) | (data->valid_rx_ant << 20); -} static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) { @@ -262,7 +248,7 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) enum iwl_ucode_type ucode_type = mvm->cur_ucode; /* Set parameters */ - phy_cfg_cmd.phy_cfg = cpu_to_le32(iwl_mvm_build_phy_cfg(mvm)); + phy_cfg_cmd.phy_cfg = cpu_to_le32(mvm->fw->phy_config); phy_cfg_cmd.calib_control.event_trigger = mvm->fw->default_calib[ucode_type].event_trigger; phy_cfg_cmd.calib_control.flow_trigger = -- cgit v1.2.3 From de8bc6dd2d52cacaa76ea381ffdc00919b100a2c Mon Sep 17 00:00:00 2001 From: Dor Shaish Date: Wed, 27 Feb 2013 13:01:09 +0200 Subject: iwlwifi: mvm: Remove overriding calibrations for the 7000 family This fix removes the override of calibration request values sent to the FW. Due to that, the sending of default values to now implemented calibrations is removed. Signed-off-by: Dor Shaish Reviewed-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw.c | 114 ---------------------------------- 1 file changed, 114 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c index d3c067e670a8..500f818dba04 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/iwlwifi/mvm/fw.c @@ -79,17 +79,8 @@ #define UCODE_VALID_OK cpu_to_le32(0x1) /* Default calibration values for WkP - set to INIT image w/o running */ -static const u8 wkp_calib_values_bb_filter[] = { 0xbf, 0x00, 0x5f, 0x00, 0x2f, - 0x00, 0x18, 0x00 }; -static const u8 wkp_calib_values_rx_dc[] = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f }; -static const u8 wkp_calib_values_tx_lo[] = { 0x00, 0x00, 0x00, 0x00 }; -static const u8 wkp_calib_values_tx_iq[] = { 0xff, 0x00, 0xff, 0x00, 0x00, - 0x00 }; -static const u8 wkp_calib_values_rx_iq[] = { 0xff, 0x00, 0x00, 0x00 }; static const u8 wkp_calib_values_rx_iq_skew[] = { 0x00, 0x00, 0x01, 0x00 }; static const u8 wkp_calib_values_tx_iq_skew[] = { 0x01, 0x00, 0x00, 0x00 }; -static const u8 wkp_calib_values_xtal[] = { 0xd2, 0xd2 }; struct iwl_calib_default_data { u16 size; @@ -99,12 +90,7 @@ struct iwl_calib_default_data { #define CALIB_SIZE_N_DATA(_buf) {.size = sizeof(_buf), .data = &_buf} static const struct iwl_calib_default_data wkp_calib_default_data[12] = { - [5] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_dc), - [6] = CALIB_SIZE_N_DATA(wkp_calib_values_bb_filter), - [7] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_lo), - [8] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq), [9] = CALIB_SIZE_N_DATA(wkp_calib_values_tx_iq_skew), - [10] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq), [11] = CALIB_SIZE_N_DATA(wkp_calib_values_rx_iq_skew), }; @@ -261,103 +247,6 @@ static int iwl_send_phy_cfg_cmd(struct iwl_mvm *mvm) sizeof(phy_cfg_cmd), &phy_cfg_cmd); } -/* Starting with the new PHY DB implementation - New calibs are enabled */ -/* Value - 0x405e7 */ -#define IWL_CALIB_DEFAULT_FLOW_INIT (IWL_CALIB_CFG_XTAL_IDX |\ - IWL_CALIB_CFG_TEMPERATURE_IDX |\ - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ - IWL_CALIB_CFG_DC_IDX |\ - IWL_CALIB_CFG_BB_FILTER_IDX |\ - IWL_CALIB_CFG_LO_LEAKAGE_IDX |\ - IWL_CALIB_CFG_TX_IQ_IDX |\ - IWL_CALIB_CFG_RX_IQ_IDX |\ - IWL_CALIB_CFG_AGC_IDX) - -#define IWL_CALIB_DEFAULT_EVENT_INIT 0x0 - -/* Value 0x41567 */ -#define IWL_CALIB_DEFAULT_FLOW_RUN (IWL_CALIB_CFG_XTAL_IDX |\ - IWL_CALIB_CFG_TEMPERATURE_IDX |\ - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ - IWL_CALIB_CFG_BB_FILTER_IDX |\ - IWL_CALIB_CFG_DC_IDX |\ - IWL_CALIB_CFG_TX_IQ_IDX |\ - IWL_CALIB_CFG_RX_IQ_IDX |\ - IWL_CALIB_CFG_SENSITIVITY_IDX |\ - IWL_CALIB_CFG_AGC_IDX) - -#define IWL_CALIB_DEFAULT_EVENT_RUN (IWL_CALIB_CFG_XTAL_IDX |\ - IWL_CALIB_CFG_TEMPERATURE_IDX |\ - IWL_CALIB_CFG_VOLTAGE_READ_IDX |\ - IWL_CALIB_CFG_TX_PWR_IDX |\ - IWL_CALIB_CFG_DC_IDX |\ - IWL_CALIB_CFG_TX_IQ_IDX |\ - IWL_CALIB_CFG_SENSITIVITY_IDX) - -/* - * Sets the calibrations trigger values that will be sent to the FW for runtime - * and init calibrations. - * The ones given in the FW TLV are not correct. - */ -static void iwl_set_default_calib_trigger(struct iwl_mvm *mvm) -{ - struct iwl_tlv_calib_ctrl default_calib; - - /* - * WkP FW TLV calib bits are wrong, overwrite them. - * This defines the dynamic calibrations which are implemented in the - * uCode both for init(flow) calculation and event driven calibs. - */ - - /* Init Image */ - default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_INIT); - default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_INIT); - - if (default_calib.event_trigger != - mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger) - IWL_ERR(mvm, - "Updating the event calib for INIT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_INIT].event_trigger, - default_calib.event_trigger); - if (default_calib.flow_trigger != - mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger) - IWL_ERR(mvm, - "Updating the flow calib for INIT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_INIT].flow_trigger, - default_calib.flow_trigger); - - memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_INIT], - &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); - IWL_ERR(mvm, - "Setting uCode init calibrations event 0x%x, trigger 0x%x\n", - default_calib.event_trigger, - default_calib.flow_trigger); - - /* Run time image */ - default_calib.event_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_EVENT_RUN); - default_calib.flow_trigger = cpu_to_le32(IWL_CALIB_DEFAULT_FLOW_RUN); - - if (default_calib.event_trigger != - mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger) - IWL_ERR(mvm, - "Updating the event calib for RT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_REGULAR].event_trigger, - default_calib.event_trigger); - if (default_calib.flow_trigger != - mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger) - IWL_ERR(mvm, - "Updating the flow calib for RT image: 0x%x -> 0x%x\n", - mvm->fw->default_calib[IWL_UCODE_REGULAR].flow_trigger, - default_calib.flow_trigger); - - memcpy((void *)&mvm->fw->default_calib[IWL_UCODE_REGULAR], - &default_calib, sizeof(struct iwl_tlv_calib_ctrl)); - IWL_ERR(mvm, - "Setting uCode runtime calibs event 0x%x, trigger 0x%x\n", - default_calib.event_trigger, - default_calib.flow_trigger); -} - static int iwl_set_default_calibrations(struct iwl_mvm *mvm) { u8 cmd_raw[16]; /* holds the variable size commands */ @@ -437,9 +326,6 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm) if (ret) goto error; - /* Override the calibrations from TLV and the const of fw */ - iwl_set_default_calib_trigger(mvm); - /* 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); -- cgit v1.2.3 From f9aa8dd33714f17c7229ad89309406a1ccb3cd3f Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Mon, 4 Mar 2013 09:11:08 +0200 Subject: iwlwifi: mvm: ignore STOP_AGG when restarting Since the device is being restarted, all the Rx / Tx Block Ack sessions are been wiped out by the driver. So ignore the requests from mac80211 that stops Tx agg while reconfiguring the device. Note that stopping a non-existing Rx BA session is harmless, so just honor mac80211's request. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/sta.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index 861a7f9f8e7f..274f44e2ef60 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c @@ -770,6 +770,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif, u16 txq_id; int err; + + /* + * If mac80211 is cleaning its state, then say that we finished since + * our state has been cleared anyway. + */ + if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) { + ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); + return 0; + } + spin_lock_bh(&mvmsta->lock); txq_id = tid_data->txq_id; -- cgit v1.2.3 From 8101a7f0656bf11c385d6e14f52313b19f017e70 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Thu, 28 Feb 2013 11:54:28 +0200 Subject: iwlwifi: mvm: update the rssi calculation Make the rssi more accurate by taking in count per-chain AGC values. Without this, the RSSI reports inaccurate values. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/fw-api.h | 18 ++++++++------- drivers/net/wireless/iwlwifi/mvm/mvm.h | 3 ++- drivers/net/wireless/iwlwifi/mvm/rx.c | 37 +++++++++++++++++++------------ 3 files changed, 35 insertions(+), 23 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 23eebda848b0..2adb61f103f4 100644 --- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h +++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h @@ -762,18 +762,20 @@ struct iwl_phy_context_cmd { #define IWL_RX_INFO_PHY_CNT 8 #define IWL_RX_INFO_AGC_IDX 1 #define IWL_RX_INFO_RSSI_AB_IDX 2 -#define IWL_RX_INFO_RSSI_C_IDX 3 -#define IWL_OFDM_AGC_DB_MSK 0xfe00 -#define IWL_OFDM_AGC_DB_POS 9 +#define IWL_OFDM_AGC_A_MSK 0x0000007f +#define IWL_OFDM_AGC_A_POS 0 +#define IWL_OFDM_AGC_B_MSK 0x00003f80 +#define IWL_OFDM_AGC_B_POS 7 +#define IWL_OFDM_AGC_CODE_MSK 0x3fe00000 +#define IWL_OFDM_AGC_CODE_POS 20 #define IWL_OFDM_RSSI_INBAND_A_MSK 0x00ff -#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 #define IWL_OFDM_RSSI_A_POS 0 +#define IWL_OFDM_RSSI_ALLBAND_A_MSK 0xff00 +#define IWL_OFDM_RSSI_ALLBAND_A_POS 8 #define IWL_OFDM_RSSI_INBAND_B_MSK 0xff0000 -#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 #define IWL_OFDM_RSSI_B_POS 16 -#define IWL_OFDM_RSSI_INBAND_C_MSK 0x00ff -#define IWL_OFDM_RSSI_ALLBAND_C_MSK 0xff00 -#define IWL_OFDM_RSSI_C_POS 0 +#define IWL_OFDM_RSSI_ALLBAND_B_MSK 0xff000000 +#define IWL_OFDM_RSSI_ALLBAND_B_POS 24 /** * struct iwl_rx_phy_info - phy info diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h index 537711b10478..bdae700c769e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mvm.h +++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h @@ -80,7 +80,8 @@ #define IWL_INVALID_MAC80211_QUEUE 0xff #define IWL_MVM_MAX_ADDRESSES 2 -#define IWL_RSSI_OFFSET 44 +/* RSSI offset for WkP */ +#define IWL_RSSI_OFFSET 50 enum iwl_mvm_tx_fifo { IWL_MVM_TX_FIFO_BK = 0, diff --git a/drivers/net/wireless/iwlwifi/mvm/rx.c b/drivers/net/wireless/iwlwifi/mvm/rx.c index 3f40ab05bbd8..b0b190d0ec23 100644 --- a/drivers/net/wireless/iwlwifi/mvm/rx.c +++ b/drivers/net/wireless/iwlwifi/mvm/rx.c @@ -131,33 +131,42 @@ static void iwl_mvm_pass_packet_to_mac80211(struct iwl_mvm *mvm, static int iwl_mvm_calc_rssi(struct iwl_mvm *mvm, struct iwl_rx_phy_info *phy_info) { - u32 rssi_a, rssi_b, rssi_c, max_rssi, agc_db; + int rssi_a, rssi_b, rssi_a_dbm, rssi_b_dbm, max_rssi_dbm; + int rssi_all_band_a, rssi_all_band_b; + u32 agc_a, agc_b, max_agc; u32 val; - /* Find max rssi among 3 possible receivers. + /* Find max rssi among 2 possible receivers. * These values are measured by the Digital Signal Processor (DSP). * They should stay fairly constant even as the signal strength varies, * if the radio's Automatic Gain Control (AGC) is working right. * AGC value (see below) will provide the "interesting" info. */ + val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); + agc_a = (val & IWL_OFDM_AGC_A_MSK) >> IWL_OFDM_AGC_A_POS; + agc_b = (val & IWL_OFDM_AGC_B_MSK) >> IWL_OFDM_AGC_B_POS; + max_agc = max_t(u32, agc_a, agc_b); + val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_AB_IDX]); rssi_a = (val & IWL_OFDM_RSSI_INBAND_A_MSK) >> IWL_OFDM_RSSI_A_POS; rssi_b = (val & IWL_OFDM_RSSI_INBAND_B_MSK) >> IWL_OFDM_RSSI_B_POS; - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_RSSI_C_IDX]); - rssi_c = (val & IWL_OFDM_RSSI_INBAND_C_MSK) >> IWL_OFDM_RSSI_C_POS; - - val = le32_to_cpu(phy_info->non_cfg_phy[IWL_RX_INFO_AGC_IDX]); - agc_db = (val & IWL_OFDM_AGC_DB_MSK) >> IWL_OFDM_AGC_DB_POS; + rssi_all_band_a = (val & IWL_OFDM_RSSI_ALLBAND_A_MSK) >> + IWL_OFDM_RSSI_ALLBAND_A_POS; + rssi_all_band_b = (val & IWL_OFDM_RSSI_ALLBAND_B_MSK) >> + IWL_OFDM_RSSI_ALLBAND_B_POS; - max_rssi = max_t(u32, rssi_a, rssi_b); - max_rssi = max_t(u32, max_rssi, rssi_c); + /* + * dBm = rssi dB - agc dB - constant. + * Higher AGC (higher radio gain) means lower signal. + */ + rssi_a_dbm = rssi_a - IWL_RSSI_OFFSET - agc_a; + rssi_b_dbm = rssi_b - IWL_RSSI_OFFSET - agc_b; + max_rssi_dbm = max_t(int, rssi_a_dbm, rssi_b_dbm); - IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d C %d Max %d AGC dB %d\n", - rssi_a, rssi_b, rssi_c, max_rssi, agc_db); + IWL_DEBUG_STATS(mvm, "Rssi In A %d B %d Max %d AGCA %d AGCB %d\n", + rssi_a_dbm, rssi_b_dbm, max_rssi_dbm, agc_a, agc_b); - /* dBm = max_rssi dB - agc dB - constant. - * Higher AGC (higher radio gain) means lower signal. */ - return max_rssi - agc_db - IWL_RSSI_OFFSET; + return max_rssi_dbm; } /* -- cgit v1.2.3 From 2470b36e84a2e680d7a7e3809cbceae5bfae3606 Mon Sep 17 00:00:00 2001 From: Emmanuel Grumbach Date: Sun, 3 Mar 2013 14:35:03 +0200 Subject: iwlwifi: mvm: don't warn on normal BAR sending This flow happens when we get a failed single Tx response on an AMPDU queue. In this case, the frame won't be sent any more. So we need to move the window on the recipient side. This is done by a BAR. Now if we are in the following case: 10, 12 and 13 are ACKed and 11 isn't. 10 11 12 13. V X V V Then, 11 will be sent 16 times as an MPDU (as oppsed to A-MPDU). If this failed, we are entering the flow described above. So we need to send a BAR with ssn = 12. But in this case, the scheduler will tell us to free frames up to 13 (included). So, it is perfectly possible to get a failed single Tx response on an AMPDU queue that makes the scheduler's ssn jump by more than 1 single packet. Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- drivers/net/wireless/iwlwifi/mvm/tx.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c index 6b67ce3f679c..6645efe5c03e 100644 --- a/drivers/net/wireless/iwlwifi/mvm/tx.c +++ b/drivers/net/wireless/iwlwifi/mvm/tx.c @@ -607,12 +607,8 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm, /* Single frame failure in an AMPDU queue => send BAR */ if (txq_id >= IWL_FIRST_AMPDU_QUEUE && - !(info->flags & IEEE80211_TX_STAT_ACK)) { - /* there must be only one skb in the skb_list */ - WARN_ON_ONCE(skb_freed > 1 || - !skb_queue_empty(&skbs)); + !(info->flags & IEEE80211_TX_STAT_ACK)) info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - } /* W/A FW bug: seq_ctl is wrong when the queue is flushed */ if (status == TX_STATUS_FAIL_FIFO_FLUSHED) { -- cgit v1.2.3 From 091930a2e612a02debe8694b41f96e33fe45bba2 Mon Sep 17 00:00:00 2001 From: Mark Langsdorf Date: Thu, 28 Feb 2013 18:29:19 +0000 Subject: mailbox, pl320-ipc: remove __init from probe function Avoids a section mismatch. Signed-off-by: Mark Langsdorf Signed-off-by: Rafael J. Wysocki --- drivers/mailbox/pl320-ipc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mailbox/pl320-ipc.c b/drivers/mailbox/pl320-ipc.c index c45b3aedafba..d873cbae2fbb 100644 --- a/drivers/mailbox/pl320-ipc.c +++ b/drivers/mailbox/pl320-ipc.c @@ -138,8 +138,7 @@ int pl320_ipc_unregister_notifier(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(pl320_ipc_unregister_notifier); -static int __init pl320_probe(struct amba_device *adev, - const struct amba_id *id) +static int pl320_probe(struct amba_device *adev, const struct amba_id *id) { int ret; -- cgit v1.2.3 From e5dde92cb2befb108ae8cfe8db68a954c164d77c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Thu, 28 Feb 2013 05:38:00 +0000 Subject: cpufreq: Fix a typo in comment Fix a typo in a comment in cpufreq_governor.h. [rjw: Changelog] Signed-off-by: Namhyung Kim Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/cpufreq_governor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/cpufreq/cpufreq_governor.h b/drivers/cpufreq/cpufreq_governor.h index d2ac91150600..46bde01eee62 100644 --- a/drivers/cpufreq/cpufreq_governor.h +++ b/drivers/cpufreq/cpufreq_governor.h @@ -64,7 +64,7 @@ static void *get_cpu_dbs_info_s(int cpu) \ * dbs: used as a shortform for demand based switching It helps to keep variable * names smaller, simpler * cdbs: common dbs - * on_*: On-demand governor + * od_*: On-demand governor * cs_*: Conservative governor */ -- cgit v1.2.3 From f5f43dcfff3a3c7f7de4a0cfca0106a0ccd58bd7 Mon Sep 17 00:00:00 2001 From: Emilio López Date: Mon, 25 Feb 2013 11:07:45 +0000 Subject: cpufreq: highbank: do not initialize array with a loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As uninitialized array members will be initialized to zero, we can avoid using a for loop by setting a value to it. Signed-off-by: Emilio López Acked-by: Viresh Kumar Acked-By: Mark Langsdorf Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/highbank-cpufreq.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/highbank-cpufreq.c b/drivers/cpufreq/highbank-cpufreq.c index 66e3a71b81a3..b61b5a3fad64 100644 --- a/drivers/cpufreq/highbank-cpufreq.c +++ b/drivers/cpufreq/highbank-cpufreq.c @@ -28,13 +28,7 @@ static int hb_voltage_change(unsigned int freq) { - int i; - u32 msg[HB_CPUFREQ_IPC_LEN]; - - msg[0] = HB_CPUFREQ_CHANGE_NOTE; - msg[1] = freq / 1000000; - for (i = 2; i < HB_CPUFREQ_IPC_LEN; i++) - msg[i] = 0; + u32 msg[HB_CPUFREQ_IPC_LEN] = {HB_CPUFREQ_CHANGE_NOTE, freq / 1000000}; return pl320_ipc_transmit(msg); } -- cgit v1.2.3 From b81ea1b5ac4d3c6a628158b736dd4a98c46c29d9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 22:48:14 +0100 Subject: PM / QoS: Fix concurrency issues and memory leaks in device PM QoS The current device PM QoS code assumes that certain functions will never be called in parallel with each other (for example, it is assumed that dev_pm_qos_expose_flags() won't be called in parallel with dev_pm_qos_hide_flags() for the same device and analogously for the latency limit), which may be overly optimistic. Moreover, dev_pm_qos_expose_flags() and dev_pm_qos_expose_latency_limit() leak memory in error code paths (req needs to be freed on errors) and __dev_pm_qos_drop_user_request() forgets to free the request. To fix the above issues put more things under the device PM QoS mutex to make them mutually exclusive and add the missing freeing of memory. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/qos.c | 129 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 87 insertions(+), 42 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 3d4d1f8aac5c..2159d62c858a 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -344,6 +344,13 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 curr_value; int ret = 0; + if (!req) /*guard against callers passing in null */ + return -EINVAL; + + if (WARN(!dev_pm_qos_request_active(req), + "%s() called for unknown object\n", __func__)) + return -EINVAL; + if (!req->dev->power.qos) return -ENODEV; @@ -386,6 +393,17 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) { int ret; + mutex_lock(&dev_pm_qos_mtx); + ret = __dev_pm_qos_update_request(req, new_value); + mutex_unlock(&dev_pm_qos_mtx); + return ret; +} +EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); + +static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req) +{ + int ret = 0; + if (!req) /*guard against callers passing in null */ return -EINVAL; @@ -393,13 +411,15 @@ int dev_pm_qos_update_request(struct dev_pm_qos_request *req, s32 new_value) "%s() called for unknown object\n", __func__)) return -EINVAL; - mutex_lock(&dev_pm_qos_mtx); - ret = __dev_pm_qos_update_request(req, new_value); - mutex_unlock(&dev_pm_qos_mtx); - + if (req->dev->power.qos) { + ret = apply_constraint(req, PM_QOS_REMOVE_REQ, + PM_QOS_DEFAULT_VALUE); + memset(req, 0, sizeof(*req)); + } else { + ret = -ENODEV; + } return ret; } -EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); /** * dev_pm_qos_remove_request - modifies an existing qos request @@ -418,26 +438,10 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); */ int dev_pm_qos_remove_request(struct dev_pm_qos_request *req) { - int ret = 0; - - if (!req) /*guard against callers passing in null */ - return -EINVAL; - - if (WARN(!dev_pm_qos_request_active(req), - "%s() called for unknown object\n", __func__)) - return -EINVAL; + int ret; mutex_lock(&dev_pm_qos_mtx); - - if (req->dev->power.qos) { - ret = apply_constraint(req, PM_QOS_REMOVE_REQ, - PM_QOS_DEFAULT_VALUE); - memset(req, 0, sizeof(*req)); - } else { - /* Return if the device has been removed */ - ret = -ENODEV; - } - + ret = __dev_pm_qos_remove_request(req); mutex_unlock(&dev_pm_qos_mtx); return ret; } @@ -563,16 +567,20 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_add_ancestor_request); static void __dev_pm_qos_drop_user_request(struct device *dev, enum dev_pm_qos_req_type type) { + struct dev_pm_qos_request *req = NULL; + switch(type) { case DEV_PM_QOS_LATENCY: - dev_pm_qos_remove_request(dev->power.qos->latency_req); + req = dev->power.qos->latency_req; dev->power.qos->latency_req = NULL; break; case DEV_PM_QOS_FLAGS: - dev_pm_qos_remove_request(dev->power.qos->flags_req); + req = dev->power.qos->flags_req; dev->power.qos->flags_req = NULL; break; } + __dev_pm_qos_remove_request(req); + kfree(req); } /** @@ -588,22 +596,36 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) if (!device_is_registered(dev) || value < 0) return -EINVAL; - if (dev->power.qos && dev->power.qos->latency_req) - return -EEXIST; - req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_LATENCY, value); - if (ret < 0) + if (ret < 0) { + kfree(req); return ret; + } + + mutex_lock(&dev_pm_qos_mtx); + + if (!dev->power.qos) + ret = -ENODEV; + else if (dev->power.qos->latency_req) + ret = -EEXIST; + + if (ret < 0) { + __dev_pm_qos_remove_request(req); + kfree(req); + goto out; + } dev->power.qos->latency_req = req; ret = pm_qos_sysfs_add_latency(dev); if (ret) __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + out: + mutex_unlock(&dev_pm_qos_mtx); return ret; } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); @@ -614,10 +636,14 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); */ void dev_pm_qos_hide_latency_limit(struct device *dev) { + mutex_lock(&dev_pm_qos_mtx); + if (dev->power.qos && dev->power.qos->latency_req) { pm_qos_sysfs_remove_latency(dev); __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); } + + mutex_unlock(&dev_pm_qos_mtx); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); @@ -634,24 +660,37 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) if (!device_is_registered(dev)) return -EINVAL; - if (dev->power.qos && dev->power.qos->flags_req) - return -EEXIST; - req = kzalloc(sizeof(*req), GFP_KERNEL); if (!req) return -ENOMEM; - pm_runtime_get_sync(dev); ret = dev_pm_qos_add_request(dev, req, DEV_PM_QOS_FLAGS, val); - if (ret < 0) - goto fail; + if (ret < 0) { + kfree(req); + return ret; + } + + pm_runtime_get_sync(dev); + mutex_lock(&dev_pm_qos_mtx); + + if (!dev->power.qos) + ret = -ENODEV; + else if (dev->power.qos->flags_req) + ret = -EEXIST; + + if (ret < 0) { + __dev_pm_qos_remove_request(req); + kfree(req); + goto out; + } dev->power.qos->flags_req = req; ret = pm_qos_sysfs_add_flags(dev); if (ret) __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); -fail: + out: + mutex_unlock(&dev_pm_qos_mtx); pm_runtime_put(dev); return ret; } @@ -663,12 +702,16 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); */ void dev_pm_qos_hide_flags(struct device *dev) { + pm_runtime_get_sync(dev); + mutex_lock(&dev_pm_qos_mtx); + if (dev->power.qos && dev->power.qos->flags_req) { pm_qos_sysfs_remove_flags(dev); - pm_runtime_get_sync(dev); __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); - pm_runtime_put(dev); } + + mutex_unlock(&dev_pm_qos_mtx); + pm_runtime_put(dev); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_flags); @@ -683,12 +726,14 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) s32 value; int ret; - if (!dev->power.qos || !dev->power.qos->flags_req) - return -EINVAL; - pm_runtime_get_sync(dev); mutex_lock(&dev_pm_qos_mtx); + if (!dev->power.qos || !dev->power.qos->flags_req) { + ret = -EINVAL; + goto out; + } + value = dev_pm_qos_requested_flags(dev); if (set) value |= mask; @@ -697,9 +742,9 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) ret = __dev_pm_qos_update_request(dev->power.qos->flags_req, value); + out: mutex_unlock(&dev_pm_qos_mtx); pm_runtime_put(dev); - return ret; } #endif /* CONFIG_PM_RUNTIME */ -- cgit v1.2.3 From 37530f2bda039774bd65aea14cc1d1dd26a82b9e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Mon, 4 Mar 2013 14:22:57 +0100 Subject: PM / QoS: Remove device PM QoS sysfs attributes at the right place Device PM QoS sysfs attributes, if present during device removal, are removed from within device_pm_remove(), which is too late, since dpm_sysfs_remove() has already removed the whole attribute group they belonged to. However, moving the removal of those attributes to dpm_sysfs_remove() alone is not sufficient, because in theory they still can be re-added right after being removed by it (the device's driver is still bound to it at that point). For this reason, move the entire desctruction of device PM QoS constraints to dpm_sysfs_remove() and make it prevent any new constraints from being added after it has run. Also, move the initialization of the power.qos field in struct device to device_pm_init_common() and drop the no longer needed dev_pm_qos_constraints_init(). Reported-by: Sasha Levin Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 2 - drivers/base/power/power.h | 8 +-- drivers/base/power/qos.c | 120 ++++++++++++++++++++------------------------- drivers/base/power/sysfs.c | 1 + 4 files changed, 55 insertions(+), 76 deletions(-) (limited to 'drivers') diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 2b7f77d3fcb0..15beb500a4e4 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -99,7 +99,6 @@ void device_pm_add(struct device *dev) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); list_add_tail(&dev->power.entry, &dpm_list); - dev_pm_qos_constraints_init(dev); mutex_unlock(&dpm_list_mtx); } @@ -113,7 +112,6 @@ void device_pm_remove(struct device *dev) dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); complete_all(&dev->power.completion); mutex_lock(&dpm_list_mtx); - dev_pm_qos_constraints_destroy(dev); list_del_init(&dev->power.entry); mutex_unlock(&dpm_list_mtx); device_wakeup_disable(dev); diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index b16686a0a5a2..cfc3226ec492 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h @@ -4,7 +4,7 @@ static inline void device_pm_init_common(struct device *dev) { if (!dev->power.early_init) { spin_lock_init(&dev->power.lock); - dev->power.power_state = PMSG_INVALID; + dev->power.qos = NULL; dev->power.early_init = true; } } @@ -56,14 +56,10 @@ extern void device_pm_move_last(struct device *); static inline void device_pm_sleep_init(struct device *dev) {} -static inline void device_pm_add(struct device *dev) -{ - dev_pm_qos_constraints_init(dev); -} +static inline void device_pm_add(struct device *dev) {} static inline void device_pm_remove(struct device *dev) { - dev_pm_qos_constraints_destroy(dev); pm_runtime_remove(dev); } diff --git a/drivers/base/power/qos.c b/drivers/base/power/qos.c index 2159d62c858a..5f74587ef258 100644 --- a/drivers/base/power/qos.c +++ b/drivers/base/power/qos.c @@ -41,6 +41,7 @@ #include #include #include +#include #include "power.h" @@ -61,7 +62,7 @@ enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask) struct pm_qos_flags *pqf; s32 val; - if (!qos) + if (IS_ERR_OR_NULL(qos)) return PM_QOS_FLAGS_UNDEFINED; pqf = &qos->flags; @@ -101,7 +102,8 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_flags); */ s32 __dev_pm_qos_read_value(struct device *dev) { - return dev->power.qos ? pm_qos_read_value(&dev->power.qos->latency) : 0; + return IS_ERR_OR_NULL(dev->power.qos) ? + 0 : pm_qos_read_value(&dev->power.qos->latency); } /** @@ -198,20 +200,8 @@ static int dev_pm_qos_constraints_allocate(struct device *dev) return 0; } -/** - * dev_pm_qos_constraints_init - Initalize device's PM QoS constraints pointer. - * @dev: target device - * - * Called from the device PM subsystem during device insertion under - * device_pm_lock(). - */ -void dev_pm_qos_constraints_init(struct device *dev) -{ - mutex_lock(&dev_pm_qos_mtx); - dev->power.qos = NULL; - dev->power.power_state = PMSG_ON; - mutex_unlock(&dev_pm_qos_mtx); -} +static void __dev_pm_qos_hide_latency_limit(struct device *dev); +static void __dev_pm_qos_hide_flags(struct device *dev); /** * dev_pm_qos_constraints_destroy @@ -226,16 +216,15 @@ void dev_pm_qos_constraints_destroy(struct device *dev) struct pm_qos_constraints *c; struct pm_qos_flags *f; + mutex_lock(&dev_pm_qos_mtx); + /* * If the device's PM QoS resume latency limit or PM QoS flags have been * exposed to user space, they have to be hidden at this point. */ - dev_pm_qos_hide_latency_limit(dev); - dev_pm_qos_hide_flags(dev); - - mutex_lock(&dev_pm_qos_mtx); + __dev_pm_qos_hide_latency_limit(dev); + __dev_pm_qos_hide_flags(dev); - dev->power.power_state = PMSG_INVALID; qos = dev->power.qos; if (!qos) goto out; @@ -257,7 +246,7 @@ void dev_pm_qos_constraints_destroy(struct device *dev) } spin_lock_irq(&dev->power.lock); - dev->power.qos = NULL; + dev->power.qos = ERR_PTR(-ENODEV); spin_unlock_irq(&dev->power.lock); kfree(c->notifiers); @@ -301,32 +290,19 @@ int dev_pm_qos_add_request(struct device *dev, struct dev_pm_qos_request *req, "%s() called for already added request\n", __func__)) return -EINVAL; - req->dev = dev; - mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.qos) { - if (dev->power.power_state.event == PM_EVENT_INVALID) { - /* The device has been removed from the system. */ - req->dev = NULL; - ret = -ENODEV; - goto out; - } else { - /* - * Allocate the constraints data on the first call to - * add_request, i.e. only if the data is not already - * allocated and if the device has not been removed. - */ - ret = dev_pm_qos_constraints_allocate(dev); - } - } + if (IS_ERR(dev->power.qos)) + ret = -ENODEV; + else if (!dev->power.qos) + ret = dev_pm_qos_constraints_allocate(dev); if (!ret) { + req->dev = dev; req->type = type; ret = apply_constraint(req, PM_QOS_ADD_REQ, value); } - out: mutex_unlock(&dev_pm_qos_mtx); return ret; @@ -351,7 +327,7 @@ static int __dev_pm_qos_update_request(struct dev_pm_qos_request *req, "%s() called for unknown object\n", __func__)) return -EINVAL; - if (!req->dev->power.qos) + if (IS_ERR_OR_NULL(req->dev->power.qos)) return -ENODEV; switch(req->type) { @@ -402,7 +378,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_update_request); static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req) { - int ret = 0; + int ret; if (!req) /*guard against callers passing in null */ return -EINVAL; @@ -411,13 +387,11 @@ static int __dev_pm_qos_remove_request(struct dev_pm_qos_request *req) "%s() called for unknown object\n", __func__)) return -EINVAL; - if (req->dev->power.qos) { - ret = apply_constraint(req, PM_QOS_REMOVE_REQ, - PM_QOS_DEFAULT_VALUE); - memset(req, 0, sizeof(*req)); - } else { - ret = -ENODEV; - } + if (IS_ERR_OR_NULL(req->dev->power.qos)) + return -ENODEV; + + ret = apply_constraint(req, PM_QOS_REMOVE_REQ, PM_QOS_DEFAULT_VALUE); + memset(req, 0, sizeof(*req)); return ret; } @@ -466,9 +440,10 @@ int dev_pm_qos_add_notifier(struct device *dev, struct notifier_block *notifier) mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.qos) - ret = dev->power.power_state.event != PM_EVENT_INVALID ? - dev_pm_qos_constraints_allocate(dev) : -ENODEV; + if (IS_ERR(dev->power.qos)) + ret = -ENODEV; + else if (!dev->power.qos) + ret = dev_pm_qos_constraints_allocate(dev); if (!ret) ret = blocking_notifier_chain_register( @@ -497,7 +472,7 @@ int dev_pm_qos_remove_notifier(struct device *dev, mutex_lock(&dev_pm_qos_mtx); /* Silently return if the constraints object is not present. */ - if (dev->power.qos) + if (!IS_ERR_OR_NULL(dev->power.qos)) retval = blocking_notifier_chain_unregister( dev->power.qos->latency.notifiers, notifier); @@ -608,7 +583,7 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.qos) + if (IS_ERR_OR_NULL(dev->power.qos)) ret = -ENODEV; else if (dev->power.qos->latency_req) ret = -EEXIST; @@ -630,6 +605,14 @@ int dev_pm_qos_expose_latency_limit(struct device *dev, s32 value) } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); +static void __dev_pm_qos_hide_latency_limit(struct device *dev) +{ + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->latency_req) { + pm_qos_sysfs_remove_latency(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); + } +} + /** * dev_pm_qos_hide_latency_limit - Hide PM QoS latency limit from user space. * @dev: Device whose PM QoS latency limit is to be hidden from user space. @@ -637,12 +620,7 @@ EXPORT_SYMBOL_GPL(dev_pm_qos_expose_latency_limit); void dev_pm_qos_hide_latency_limit(struct device *dev) { mutex_lock(&dev_pm_qos_mtx); - - if (dev->power.qos && dev->power.qos->latency_req) { - pm_qos_sysfs_remove_latency(dev); - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_LATENCY); - } - + __dev_pm_qos_hide_latency_limit(dev); mutex_unlock(&dev_pm_qos_mtx); } EXPORT_SYMBOL_GPL(dev_pm_qos_hide_latency_limit); @@ -673,7 +651,7 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) pm_runtime_get_sync(dev); mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.qos) + if (IS_ERR_OR_NULL(dev->power.qos)) ret = -ENODEV; else if (dev->power.qos->flags_req) ret = -EEXIST; @@ -696,6 +674,14 @@ int dev_pm_qos_expose_flags(struct device *dev, s32 val) } EXPORT_SYMBOL_GPL(dev_pm_qos_expose_flags); +static void __dev_pm_qos_hide_flags(struct device *dev) +{ + if (!IS_ERR_OR_NULL(dev->power.qos) && dev->power.qos->flags_req) { + pm_qos_sysfs_remove_flags(dev); + __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); + } +} + /** * dev_pm_qos_hide_flags - Hide PM QoS flags of a device from user space. * @dev: Device whose PM QoS flags are to be hidden from user space. @@ -704,12 +690,7 @@ void dev_pm_qos_hide_flags(struct device *dev) { pm_runtime_get_sync(dev); mutex_lock(&dev_pm_qos_mtx); - - if (dev->power.qos && dev->power.qos->flags_req) { - pm_qos_sysfs_remove_flags(dev); - __dev_pm_qos_drop_user_request(dev, DEV_PM_QOS_FLAGS); - } - + __dev_pm_qos_hide_flags(dev); mutex_unlock(&dev_pm_qos_mtx); pm_runtime_put(dev); } @@ -729,7 +710,7 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) pm_runtime_get_sync(dev); mutex_lock(&dev_pm_qos_mtx); - if (!dev->power.qos || !dev->power.qos->flags_req) { + if (IS_ERR_OR_NULL(dev->power.qos) || !dev->power.qos->flags_req) { ret = -EINVAL; goto out; } @@ -747,4 +728,7 @@ int dev_pm_qos_update_flags(struct device *dev, s32 mask, bool set) pm_runtime_put(dev); return ret; } +#else /* !CONFIG_PM_RUNTIME */ +static void __dev_pm_qos_hide_latency_limit(struct device *dev) {} +static void __dev_pm_qos_hide_flags(struct device *dev) {} #endif /* CONFIG_PM_RUNTIME */ diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index 50d16e3cb0a9..a53ebd265701 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c @@ -708,6 +708,7 @@ void rpm_sysfs_remove(struct device *dev) void dpm_sysfs_remove(struct device *dev) { + dev_pm_qos_constraints_destroy(dev); rpm_sysfs_remove(dev); sysfs_unmerge_group(&dev->kobj, &pm_wakeup_attr_group); sysfs_remove_group(&dev->kobj, &pm_attr_group); -- cgit v1.2.3 From ed4cf5b23f9d21c441e5c8feead86f2e4a436923 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 22 Feb 2013 07:37:36 +0000 Subject: ACPI / Sleep: Avoid interleaved message on errors Got this dmesg log on an Acer Aspire 725. [ 0.256351] ACPI: (supports S0ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S1_] (20130117/hwxface-568) [ 0.256373] ACPI Exception: AE_NOT_FOUND, While evaluating Sleep State [\_S2_] (20130117/hwxface-568) [ 0.256391] S3 S4 S5) Avoid this interleaving error messages. Signed-off-by: Joe Perches Signed-off-by: Rafael J. Wysocki --- drivers/acpi/sleep.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 6d3a06a629a1..24213033fbae 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -599,7 +599,6 @@ static void acpi_sleep_suspend_setup(void) status = acpi_get_sleep_type_data(i, &type_a, &type_b); if (ACPI_SUCCESS(status)) { sleep_states[i] = 1; - pr_cont(" S%d", i); } } @@ -742,7 +741,6 @@ static void acpi_sleep_hibernate_setup(void) hibernation_set_ops(old_suspend_ordering ? &acpi_hibernation_ops_old : &acpi_hibernation_ops); sleep_states[ACPI_STATE_S4] = 1; - pr_cont(KERN_CONT " S4"); if (nosigcheck) return; @@ -788,6 +786,9 @@ int __init acpi_sleep_init(void) { acpi_status status; u8 type_a, type_b; + char supported[ACPI_S_STATE_COUNT * 3 + 1]; + char *pos = supported; + int i; if (acpi_disabled) return 0; @@ -795,7 +796,6 @@ int __init acpi_sleep_init(void) acpi_sleep_dmi_check(); sleep_states[ACPI_STATE_S0] = 1; - pr_info(PREFIX "(supports S0"); acpi_sleep_suspend_setup(); acpi_sleep_hibernate_setup(); @@ -803,11 +803,17 @@ int __init acpi_sleep_init(void) status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b); if (ACPI_SUCCESS(status)) { sleep_states[ACPI_STATE_S5] = 1; - pr_cont(" S5"); pm_power_off_prepare = acpi_power_off_prepare; pm_power_off = acpi_power_off; } - pr_cont(")\n"); + + supported[0] = 0; + for (i = 0; i < ACPI_S_STATE_COUNT; i++) { + if (sleep_states[i]) + pos += sprintf(pos, " S%d", i); + } + pr_info(PREFIX "(supports%s)\n", supported); + /* * Register the tts_notifier to reboot notifier list so that the _TTS * object can also be evaluated when the system enters S5. -- cgit v1.2.3 From 5273a258373a84bbbcbccabb356de5b68e2b8931 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Sun, 24 Feb 2013 23:12:53 +0000 Subject: ACPI / processor: Remove redundant NULL check before kfree kfree() on a NULL pointer is a no-op, so remove a redundant NULL pointer check in map_mat_entry(). [rjw: Changelog] Signed-off-by: Syam Sidhardhan Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index eff722278ff5..164d49569aeb 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -158,8 +158,7 @@ static int map_mat_entry(acpi_handle handle, int type, u32 acpi_id) } exit: - if (buffer.pointer) - kfree(buffer.pointer); + kfree(buffer.pointer); return apic_id; } -- cgit v1.2.3 From 9b27516fcd7ab7dc416edf418446c24c61729938 Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Wed, 27 Feb 2013 04:27:30 +0000 Subject: ACPI / porocessor: Beautify code, pr->id is u32 which is never < 0 pr->id is u32 which never < 0, so remove the redundant pr->id < 0 check from acpi_processor_add(). [rjw: Changelog] Signed-off-by: Chen Gang Signed-off-by: Rafael J. Wysocki --- drivers/acpi/processor_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index df34bd04ae62..bec717ffd25f 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -559,7 +559,7 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) return 0; #endif - BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); + BUG_ON(pr->id >= nr_cpu_ids); /* * Buggy BIOS check -- cgit v1.2.3 From 53540098b23c3884b4a0b4f220b9d977bc496af3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 22:35:20 +0100 Subject: ACPI / glue: Add .match() callback to struct acpi_bus_type USB uses the .find_bridge() callback from struct acpi_bus_type incorrectly, because as a result of the way it is used by USB every device in the system that doesn't have a bus type or parent is passed to usb_acpi_find_device() for inspection. What USB actually needs, though, is to call usb_acpi_find_device() for USB ports that don't have a bus type defined, but have usb_port_device_type as their device type, as well as for USB devices. To fix that replace the struct bus_type pointer in struct acpi_bus_type used for matching devices to specific subsystems with a .match() callback to be used for this purpose and update the users of struct acpi_bus_type, including USB, accordingly. Define the .match() callback routine for USB, usb_acpi_bus_match(), in such a way that it will cover both USB devices and USB ports and remove the now redundant .find_bridge() callback pointer from usb_acpi_bus. Signed-off-by: Rafael J. Wysocki Acked-by: Greg Kroah-Hartman Acked-by: Yinghai Lu Acked-by: Jeff Garzik --- drivers/acpi/glue.c | 39 +++++++++++++-------------------------- drivers/ata/libata-acpi.c | 1 + drivers/pci/pci-acpi.c | 8 +++++++- drivers/pnp/pnpacpi/core.c | 8 +++++++- drivers/scsi/scsi_lib.c | 7 ++++++- drivers/usb/core/usb-acpi.c | 9 +++++++-- include/acpi/acpi_bus.h | 3 ++- 7 files changed, 43 insertions(+), 32 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index ef6f155469b5..b94d14721af3 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -36,12 +36,11 @@ int register_acpi_bus_type(struct acpi_bus_type *type) { if (acpi_disabled) return -ENODEV; - if (type && type->bus && type->find_device) { + if (type && type->match && type->find_device) { down_write(&bus_type_sem); list_add_tail(&type->list, &bus_type_list); up_write(&bus_type_sem); - printk(KERN_INFO PREFIX "bus type %s registered\n", - type->bus->name); + printk(KERN_INFO PREFIX "bus type %s registered\n", type->name); return 0; } return -ENODEV; @@ -56,24 +55,21 @@ int unregister_acpi_bus_type(struct acpi_bus_type *type) down_write(&bus_type_sem); list_del_init(&type->list); up_write(&bus_type_sem); - printk(KERN_INFO PREFIX "ACPI bus type %s unregistered\n", - type->bus->name); + printk(KERN_INFO PREFIX "bus type %s unregistered\n", + type->name); return 0; } return -ENODEV; } EXPORT_SYMBOL_GPL(unregister_acpi_bus_type); -static struct acpi_bus_type *acpi_get_bus_type(struct bus_type *type) +static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) { struct acpi_bus_type *tmp, *ret = NULL; - if (!type) - return NULL; - down_read(&bus_type_sem); list_for_each_entry(tmp, &bus_type_list, list) { - if (tmp->bus == type) { + if (tmp->match(dev)) { ret = tmp; break; } @@ -261,26 +257,17 @@ err: static int acpi_platform_notify(struct device *dev) { - struct acpi_bus_type *type; + struct acpi_bus_type *type = acpi_get_bus_type(dev); acpi_handle handle; int ret; ret = acpi_bind_one(dev, NULL); - if (ret && (!dev->bus || !dev->parent)) { - /* bridge devices genernally haven't bus or parent */ - ret = acpi_find_bridge_device(dev, &handle); - if (!ret) { - ret = acpi_bind_one(dev, handle); - if (ret) - goto out; - } - } - - type = acpi_get_bus_type(dev->bus); if (ret) { - if (!type || !type->find_device) { - DBG("No ACPI bus support for %s\n", dev_name(dev)); - ret = -EINVAL; + if (!type) { + ret = acpi_find_bridge_device(dev, &handle); + if (!ret) + ret = acpi_bind_one(dev, handle); + goto out; } @@ -316,7 +303,7 @@ static int acpi_platform_notify_remove(struct device *dev) { struct acpi_bus_type *type; - type = acpi_get_bus_type(dev->bus); + type = acpi_get_bus_type(dev); if (type && type->cleanup) type->cleanup(dev); diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 0ea1018280bd..c832a5ca09ad 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1150,6 +1150,7 @@ static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle) } static struct acpi_bus_type ata_acpi_bus = { + .name = "ATA", .find_bridge = ata_acpi_find_dummy, .find_device = ata_acpi_find_device, }; diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 39c937f9b426..dee5dddaa292 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -331,8 +331,14 @@ static void pci_acpi_cleanup(struct device *dev) } } +static bool pci_acpi_bus_match(struct device *dev) +{ + return dev->bus == &pci_bus_type; +} + static struct acpi_bus_type acpi_pci_bus = { - .bus = &pci_bus_type, + .name = "PCI", + .match = pci_acpi_bus_match, .find_device = acpi_pci_find_device, .setup = pci_acpi_setup, .cleanup = pci_acpi_cleanup, diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 8813fc03aa09..55cd459a3908 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -353,8 +353,14 @@ static int __init acpi_pnp_find_device(struct device *dev, acpi_handle * handle) /* complete initialization of a PNPACPI device includes having * pnpdev->dev.archdata.acpi_handle point to its ACPI sibling. */ +static bool acpi_pnp_bus_match(struct device *dev) +{ + return dev->bus == &pnp_bus_type; +} + static struct acpi_bus_type __initdata acpi_pnp_bus = { - .bus = &pnp_bus_type, + .name = "PNP", + .match = acpi_pnp_bus_match, .find_device = acpi_pnp_find_device, }; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 765398c063c7..c31187d79343 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -71,9 +71,14 @@ struct kmem_cache *scsi_sdb_cache; #ifdef CONFIG_ACPI #include +static bool acpi_scsi_bus_match(struct device *dev) +{ + return dev->bus == &scsi_bus_type; +} + int scsi_register_acpi_bus_type(struct acpi_bus_type *bus) { - bus->bus = &scsi_bus_type; + bus->match = acpi_scsi_bus_match; return register_acpi_bus_type(bus); } EXPORT_SYMBOL_GPL(scsi_register_acpi_bus_type); diff --git a/drivers/usb/core/usb-acpi.c b/drivers/usb/core/usb-acpi.c index cef4252bb31a..b6f4bad3f756 100644 --- a/drivers/usb/core/usb-acpi.c +++ b/drivers/usb/core/usb-acpi.c @@ -210,9 +210,14 @@ static int usb_acpi_find_device(struct device *dev, acpi_handle *handle) return 0; } +static bool usb_acpi_bus_match(struct device *dev) +{ + return is_usb_device(dev) || is_usb_port(dev); +} + static struct acpi_bus_type usb_acpi_bus = { - .bus = &usb_bus_type, - .find_bridge = usb_acpi_find_device, + .name = "USB", + .match = usb_acpi_bus_match, .find_device = usb_acpi_find_device, }; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index e65278f560c4..c751d7de3a5f 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -437,7 +437,8 @@ void acpi_remove_dir(struct acpi_device *); */ struct acpi_bus_type { struct list_head list; - struct bus_type *bus; + const char *name; + bool (*match)(struct device *dev); /* For general devices under the bus */ int (*find_device) (struct device *, acpi_handle *); /* For bridges, such as PCI root bridge, IDE controller */ -- cgit v1.2.3 From 924144818cf0edc5d9d70d3a44e7cbbf4544796c Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 3 Mar 2013 22:35:44 +0100 Subject: ACPI / glue: Drop .find_bridge() callback from struct acpi_bus_type After PCI and USB have stopped using the .find_bridge() callback in struct acpi_bus_type, the only remaining user of it is SATA, but SATA only pretends to be a user, because it points that callback to a stub always returning -ENODEV. For this reason, drop the SATA's dummy .find_bridge() callback and remove .find_bridge(), which is not used any more, from struct acpi_bus_type entirely. Signed-off-by: Rafael J. Wysocki Acked-by: Yinghai Lu Acked-by: Jeff Garzik --- drivers/acpi/glue.c | 26 +------------------------- drivers/ata/libata-acpi.c | 6 ------ include/acpi/acpi_bus.h | 3 --- 3 files changed, 1 insertion(+), 34 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index b94d14721af3..40a84cc6740c 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -78,22 +78,6 @@ static struct acpi_bus_type *acpi_get_bus_type(struct device *dev) return ret; } -static int acpi_find_bridge_device(struct device *dev, acpi_handle * handle) -{ - struct acpi_bus_type *tmp; - int ret = -ENODEV; - - down_read(&bus_type_sem); - list_for_each_entry(tmp, &bus_type_list, list) { - if (tmp->find_bridge && !tmp->find_bridge(dev, handle)) { - ret = 0; - break; - } - } - up_read(&bus_type_sem); - return ret; -} - static acpi_status do_acpi_find_child(acpi_handle handle, u32 lvl_not_used, void *addr_p, void **ret_p) { @@ -262,15 +246,7 @@ static int acpi_platform_notify(struct device *dev) int ret; ret = acpi_bind_one(dev, NULL); - if (ret) { - if (!type) { - ret = acpi_find_bridge_device(dev, &handle); - if (!ret) - ret = acpi_bind_one(dev, handle); - - goto out; - } - + if (ret && type) { ret = type->find_device(dev, &handle); if (ret) { DBG("Unable to get handle for %s\n", dev_name(dev)); diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index c832a5ca09ad..beea3115577e 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1144,14 +1144,8 @@ static int ata_acpi_find_device(struct device *dev, acpi_handle *handle) return -ENODEV; } -static int ata_acpi_find_dummy(struct device *dev, acpi_handle *handle) -{ - return -ENODEV; -} - static struct acpi_bus_type ata_acpi_bus = { .name = "ATA", - .find_bridge = ata_acpi_find_dummy, .find_device = ata_acpi_find_device, }; diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c751d7de3a5f..22ba56e834e2 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -439,10 +439,7 @@ struct acpi_bus_type { struct list_head list; const char *name; bool (*match)(struct device *dev); - /* For general devices under the bus */ int (*find_device) (struct device *, acpi_handle *); - /* For bridges, such as PCI root bridge, IDE controller */ - int (*find_bridge) (struct device *, acpi_handle *); void (*setup)(struct device *); void (*cleanup)(struct device *); }; -- cgit v1.2.3 From 61bc95c1fbbb6a08b55bbe161fdf1ea5493fc595 Mon Sep 17 00:00:00 2001 From: Egbert Eich Date: Mon, 4 Mar 2013 09:24:38 -0500 Subject: DRM/i915: On G45 enable cursor plane briefly after enabling the display plane. On G45 some low res modes (800x600 and 1024x768) produce a blank screen when the display plane is enabled with with cursor plane off. Experiments showed that this issue occurred when the following conditions were met: a. a previous mode had the cursor plane enabled (Xserver). b. this mode or the previous one was using self refresh. (Thus the problem was only seen with low res modes). The screens lit up as soon as the cursor plane got enabled. Therefore the blank screen occurred only in console mode, not when running an Xserver. It also seemed to be necessary to disable self refresh while briefly enabling the cursor plane. Signed-off-by: Egbert Eich Bugzilla: https://bugs.freedesktop.org/attachment.cgi?bugid=61457 Acked-by: Chris Wilson [danvet: drop spurious whitespace change.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 09659ff6d24d..0a02e044b653 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3604,6 +3604,30 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) */ } +/** + * i9xx_fixup_plane - ugly workaround for G45 to fire up the hardware + * cursor plane briefly if not already running after enabling the display + * plane. + * This workaround avoids occasional blank screens when self refresh is + * enabled. + */ +static void +g4x_fixup_plane(struct drm_i915_private *dev_priv, enum pipe pipe) +{ + u32 cntl = I915_READ(CURCNTR(pipe)); + + if ((cntl & CURSOR_MODE) == 0) { + u32 fw_bcl_self = I915_READ(FW_BLC_SELF); + + I915_WRITE(FW_BLC_SELF, fw_bcl_self & ~FW_BLC_SELF_EN); + I915_WRITE(CURCNTR(pipe), CURSOR_MODE_64_ARGB_AX); + intel_wait_for_vblank(dev_priv->dev, pipe); + I915_WRITE(CURCNTR(pipe), cntl); + I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe))); + I915_WRITE(FW_BLC_SELF, fw_bcl_self); + } +} + static void i9xx_crtc_enable(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; @@ -3629,6 +3653,8 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) intel_enable_pipe(dev_priv, pipe, false); intel_enable_plane(dev_priv, plane, pipe); + if (IS_G4X(dev)) + g4x_fixup_plane(dev_priv, pipe); intel_crtc_load_lut(crtc); intel_update_fbc(dev); -- cgit v1.2.3 From b980955236922ae6106774511c5c05003d3ad225 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 4 Mar 2013 11:59:12 -0500 Subject: random: fix locking dependency with the tasklist_lock Commit 6133705494bb introduced a circular lock dependency because posix_cpu_timers_exit() is called by release_task(), which is holding a writer lock on tasklist_lock, and this can cause a deadlock since kill_fasync() gets called with nonblocking_pool.lock taken. There's no reason why kill_fasync() needs to be taken while the random pool is locked, so move it out to fix this locking dependency. Signed-off-by: "Theodore Ts'o" Reported-by: Russ Dill Cc: stable@kernel.org --- drivers/char/random.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/random.c b/drivers/char/random.c index 85e81ec1451e..57d4b152267c 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -852,6 +852,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, int reserved) { unsigned long flags; + int wakeup_write = 0; /* Hold lock while accounting */ spin_lock_irqsave(&r->lock, flags); @@ -873,10 +874,8 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, else r->entropy_count = reserved; - if (r->entropy_count < random_write_wakeup_thresh) { - wake_up_interruptible(&random_write_wait); - kill_fasync(&fasync, SIGIO, POLL_OUT); - } + if (r->entropy_count < random_write_wakeup_thresh) + wakeup_write = 1; } DEBUG_ENT("debiting %zu entropy credits from %s%s\n", @@ -884,6 +883,11 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, spin_unlock_irqrestore(&r->lock, flags); + if (wakeup_write) { + wake_up_interruptible(&random_write_wait); + kill_fasync(&fasync, SIGIO, POLL_OUT); + } + return nbytes; } -- cgit v1.2.3 From de5fb0a053482d89262c3284b67884cd2c621adc Mon Sep 17 00:00:00 2001 From: Frank Li Date: Sun, 3 Mar 2013 17:34:25 +0000 Subject: net: fec: put tx to napi poll function to fix dead lock up stack ndo_start_xmit already hold lock. fec_enet_start_xmit needn't spin lock. stat_xmit just update fep->cur_tx fec_enet_tx just update fep->dirty_tx Reserve a empty bdb to check full or empty cur_tx == dirty_tx means full cur_tx == dirty_tx +1 means empty So needn't is_full variable. Fix spin lock deadlock ================================= [ INFO: inconsistent lock state ] 3.8.0-rc5+ #107 Not tainted --------------------------------- inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage. ptp4l/615 [HC1[1]:SC0[0]:HE0:SE1] takes: (&(&list->lock)->rlock#3){?.-...}, at: [<8042c3c4>] skb_queue_tail+0x20/0x50 {HARDIRQ-ON-W} state was registered at: [<80067250>] mark_lock+0x154/0x4e8 [<800676f4>] mark_irqflags+0x110/0x1a4 [<80069208>] __lock_acquire+0x494/0x9c0 [<80069ce8>] lock_acquire+0x90/0xa4 [<80527ad0>] _raw_spin_lock_bh+0x44/0x54 [<804877e0>] first_packet_length+0x38/0x1f0 [<804879e4>] udp_poll+0x4c/0x5c [<804231f8>] sock_poll+0x24/0x28 [<800d27f0>] do_poll.isra.10+0x120/0x254 [<800d36e4>] do_sys_poll+0x15c/0x1e8 [<800d3828>] sys_poll+0x60/0xc8 [<8000e780>] ret_fast_syscall+0x0/0x3c *** DEADLOCK *** 1 lock held by ptp4l/615: #0: (&(&fep->hw_lock)->rlock){-.-...}, at: [<80355f9c>] fec_enet_tx+0x24/0x268 stack backtrace: Backtrace: [<800121e0>] (dump_backtrace+0x0/0x10c) from [<80516210>] (dump_stack+0x18/0x1c) r6:8063b1fc r5:bf38b2f8 r4:bf38b000 r3:bf38b000 [<805161f8>] (dump_stack+0x0/0x1c) from [<805189d0>] (print_usage_bug.part.34+0x164/0x1a4) [<8051886c>] (print_usage_bug.part.34+0x0/0x1a4) from [<80518a88>] (print_usage_bug+0x78/0x88) r8:80065664 r7:bf38b2f8 r6:00000002 r5:00000000 r4:bf38b000 [<80518a10>] (print_usage_bug+0x0/0x88) from [<80518b58>] (mark_lock_irq+0xc0/0x270) r7:bf38b000 r6:00000002 r5:bf38b2f8 r4:00000000 [<80518a98>] (mark_lock_irq+0x0/0x270) from [<80067270>] (mark_lock+0x174/0x4e8) [<800670fc>] (mark_lock+0x0/0x4e8) from [<80067744>] (mark_irqflags+0x160/0x1a4) [<800675e4>] (mark_irqflags+0x0/0x1a4) from [<80069208>] (__lock_acquire+0x494/0x9c0) r5:00000002 r4:bf38b2f8 [<80068d74>] (__lock_acquire+0x0/0x9c0) from [<80069ce8>] (lock_acquire+0x90/0xa4) [<80069c58>] (lock_acquire+0x0/0xa4) from [<805278d8>] (_raw_spin_lock_irqsave+0x4c/0x60) [<8052788c>] (_raw_spin_lock_irqsave+0x0/0x60) from [<8042c3c4>] (skb_queue_tail+0x20/0x50) r6:bfbb2180 r5:bf1d0190 r4:bf1d0184 [<8042c3a4>] (skb_queue_tail+0x0/0x50) from [<8042c4cc>] (sock_queue_err_skb+0xd8/0x188) r6:00000056 r5:bfbb2180 r4:bf1d0000 r3:00000000 [<8042c3f4>] (sock_queue_err_skb+0x0/0x188) from [<8042d15c>] (skb_tstamp_tx+0x70/0xa0) r6:bf0dddb0 r5:bf1d0000 r4:bfbb2180 r3:00000004 [<8042d0ec>] (skb_tstamp_tx+0x0/0xa0) from [<803561d0>] (fec_enet_tx+0x258/0x268) r6:c089d260 r5:00001c00 r4:bfbd0000 [<80355f78>] (fec_enet_tx+0x0/0x268) from [<803562cc>] (fec_enet_interrupt+0xec/0xf8) [<803561e0>] (fec_enet_interrupt+0x0/0xf8) from [<8007d5b0>] (handle_irq_event_percpu+0x54/0x1a0) [<8007d55c>] (handle_irq_event_percpu+0x0/0x1a0) from [<8007d740>] (handle_irq_event+0x44/0x64) [<8007d6fc>] (handle_irq_event+0x0/0x64) from [<80080690>] (handle_fasteoi_irq+0xc4/0x15c) r6:bf0dc000 r5:bf811290 r4:bf811240 r3:00000000 [<800805cc>] (handle_fasteoi_irq+0x0/0x15c) from [<8007ceec>] (generic_handle_irq+0x28/0x38) r5:807130c8 r4:00000096 [<8007cec4>] (generic_handle_irq+0x0/0x38) from [<8000f16c>] (handle_IRQ+0x54/0xb4) r4:8071d280 r3:00000180 [<8000f118>] (handle_IRQ+0x0/0xb4) from [<80008544>] (gic_handle_irq+0x30/0x64) r8:8000e924 r7:f4000100 r6:bf0ddef8 r5:8071c974 r4:f400010c r3:00000000 [<80008514>] (gic_handle_irq+0x0/0x64) from [<8000e2e4>] (__irq_svc+0x44/0x5c) Exception stack(0xbf0ddef8 to 0xbf0ddf40) Signed-off-by: Frank Li Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 85 +++++++++++++++++------------------- drivers/net/ethernet/freescale/fec.h | 3 -- 2 files changed, 41 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index fccc3bf2141d..069a155d16ed 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -246,14 +246,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) struct bufdesc *bdp; void *bufaddr; unsigned short status; - unsigned long flags; + unsigned int index; if (!fep->link) { /* Link is down or autonegotiation is in progress. */ return NETDEV_TX_BUSY; } - spin_lock_irqsave(&fep->hw_lock, flags); /* Fill in a Tx ring entry */ bdp = fep->cur_tx; @@ -264,7 +263,6 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) * This should not happen, since ndev->tbusy should be set. */ printk("%s: tx queue full!.\n", ndev->name); - spin_unlock_irqrestore(&fep->hw_lock, flags); return NETDEV_TX_BUSY; } @@ -280,13 +278,13 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) * 4-byte boundaries. Use bounce buffers to copy data * and get it aligned. Ugh. */ + if (fep->bufdesc_ex) + index = (struct bufdesc_ex *)bdp - + (struct bufdesc_ex *)fep->tx_bd_base; + else + index = bdp - fep->tx_bd_base; + if (((unsigned long) bufaddr) & FEC_ALIGNMENT) { - unsigned int index; - if (fep->bufdesc_ex) - index = (struct bufdesc_ex *)bdp - - (struct bufdesc_ex *)fep->tx_bd_base; - else - index = bdp - fep->tx_bd_base; memcpy(fep->tx_bounce[index], skb->data, skb->len); bufaddr = fep->tx_bounce[index]; } @@ -300,10 +298,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) swap_buffer(bufaddr, skb->len); /* Save skb pointer */ - fep->tx_skbuff[fep->skb_cur] = skb; - - ndev->stats.tx_bytes += skb->len; - fep->skb_cur = (fep->skb_cur+1) & TX_RING_MOD_MASK; + fep->tx_skbuff[index] = skb; /* Push the data cache so the CPM does not get stale memory * data. @@ -331,26 +326,22 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev) ebdp->cbd_esc = BD_ENET_TX_INT; } } - /* Trigger transmission start */ - writel(0, fep->hwp + FEC_X_DES_ACTIVE); - /* If this was the last BD in the ring, start at the beginning again. */ if (status & BD_ENET_TX_WRAP) bdp = fep->tx_bd_base; else bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); - if (bdp == fep->dirty_tx) { - fep->tx_full = 1; + fep->cur_tx = bdp; + + if (fep->cur_tx == fep->dirty_tx) netif_stop_queue(ndev); - } - fep->cur_tx = bdp; + /* Trigger transmission start */ + writel(0, fep->hwp + FEC_X_DES_ACTIVE); skb_tx_timestamp(skb); - spin_unlock_irqrestore(&fep->hw_lock, flags); - return NETDEV_TX_OK; } @@ -406,11 +397,8 @@ fec_restart(struct net_device *ndev, int duplex) writel((unsigned long)fep->bd_dma + sizeof(struct bufdesc) * RX_RING_SIZE, fep->hwp + FEC_X_DES_START); - fep->dirty_tx = fep->cur_tx = fep->tx_bd_base; fep->cur_rx = fep->rx_bd_base; - /* Reset SKB transmit buffers. */ - fep->skb_cur = fep->skb_dirty = 0; for (i = 0; i <= TX_RING_MOD_MASK; i++) { if (fep->tx_skbuff[i]) { dev_kfree_skb_any(fep->tx_skbuff[i]); @@ -573,20 +561,35 @@ fec_enet_tx(struct net_device *ndev) struct bufdesc *bdp; unsigned short status; struct sk_buff *skb; + int index = 0; fep = netdev_priv(ndev); - spin_lock(&fep->hw_lock); bdp = fep->dirty_tx; + /* get next bdp of dirty_tx */ + if (bdp->cbd_sc & BD_ENET_TX_WRAP) + bdp = fep->tx_bd_base; + else + bdp = fec_enet_get_nextdesc(bdp, fep->bufdesc_ex); + while (((status = bdp->cbd_sc) & BD_ENET_TX_READY) == 0) { - if (bdp == fep->cur_tx && fep->tx_full == 0) + + /* current queue is empty */ + if (bdp == fep->cur_tx) break; + if (fep->bufdesc_ex) + index = (struct bufdesc_ex *)bdp - + (struct bufdesc_ex *)fep->tx_bd_base; + else + index = bdp - fep->tx_bd_base; + dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr, FEC_ENET_TX_FRSIZE, DMA_TO_DEVICE); bdp->cbd_bufaddr = 0; - skb = fep->tx_skbuff[fep->skb_dirty]; + skb = fep->tx_skbuff[index]; + /* Check for errors. */ if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN | @@ -631,8 +634,9 @@ fec_enet_tx(struct net_device *ndev) /* Free the sk buffer associated with this last transmit */ dev_kfree_skb_any(skb); - fep->tx_skbuff[fep->skb_dirty] = NULL; - fep->skb_dirty = (fep->skb_dirty + 1) & TX_RING_MOD_MASK; + fep->tx_skbuff[index] = NULL; + + fep->dirty_tx = bdp; /* Update pointer to next buffer descriptor to be transmitted */ if (status & BD_ENET_TX_WRAP) @@ -642,14 +646,12 @@ fec_enet_tx(struct net_device *ndev) /* Since we have freed up a buffer, the ring is no longer full */ - if (fep->tx_full) { - fep->tx_full = 0; + if (fep->dirty_tx != fep->cur_tx) { if (netif_queue_stopped(ndev)) netif_wake_queue(ndev); } } - fep->dirty_tx = bdp; - spin_unlock(&fep->hw_lock); + return; } @@ -816,7 +818,7 @@ fec_enet_interrupt(int irq, void *dev_id) int_events = readl(fep->hwp + FEC_IEVENT); writel(int_events, fep->hwp + FEC_IEVENT); - if (int_events & FEC_ENET_RXF) { + if (int_events & (FEC_ENET_RXF | FEC_ENET_TXF)) { ret = IRQ_HANDLED; /* Disable the RX interrupt */ @@ -827,15 +829,6 @@ fec_enet_interrupt(int irq, void *dev_id) } } - /* Transmit OK, or non-fatal error. Update the buffer - * descriptors. FEC handles all errors, we just discover - * them as part of the transmit process. - */ - if (int_events & FEC_ENET_TXF) { - ret = IRQ_HANDLED; - fec_enet_tx(ndev); - } - if (int_events & FEC_ENET_MII) { ret = IRQ_HANDLED; complete(&fep->mdio_done); @@ -851,6 +844,8 @@ static int fec_enet_rx_napi(struct napi_struct *napi, int budget) int pkts = fec_enet_rx(ndev, budget); struct fec_enet_private *fep = netdev_priv(ndev); + fec_enet_tx(ndev); + if (pkts < budget) { napi_complete(napi); writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); @@ -1646,6 +1641,7 @@ static int fec_enet_init(struct net_device *ndev) /* ...and the same for transmit */ bdp = fep->tx_bd_base; + fep->cur_tx = bdp; for (i = 0; i < TX_RING_SIZE; i++) { /* Initialize the BD for every fragment in the page. */ @@ -1657,6 +1653,7 @@ static int fec_enet_init(struct net_device *ndev) /* Set the last buffer to wrap */ bdp = fec_enet_get_prevdesc(bdp, fep->bufdesc_ex); bdp->cbd_sc |= BD_SC_WRAP; + fep->dirty_tx = bdp; fec_restart(ndev, 0); diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index 01579b8e37c4..c0f63be91ff7 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -214,8 +214,6 @@ struct fec_enet_private { unsigned char *tx_bounce[TX_RING_SIZE]; struct sk_buff *tx_skbuff[TX_RING_SIZE]; struct sk_buff *rx_skbuff[RX_RING_SIZE]; - ushort skb_cur; - ushort skb_dirty; /* CPM dual port RAM relative addresses */ dma_addr_t bd_dma; @@ -227,7 +225,6 @@ struct fec_enet_private { /* The ring entries to be free()ed */ struct bufdesc *dirty_tx; - uint tx_full; /* hold while accessing the HW like ringbuffer for tx/rx but not MAC */ spinlock_t hw_lock; -- cgit v1.2.3 From acac8406cd523a3afbd6c6db31e9f763644bf6ba Mon Sep 17 00:00:00 2001 From: Frank Li Date: Sun, 3 Mar 2013 20:52:38 +0000 Subject: net: fec: fix build error in no MXC platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build error cause by Commit ff43da86c69d76a726ffe7d1666148960dc1d108 ("NET: FEC: dynamtic check DMA desc buff type") drivers/net/ethernet/freescale/fec.c: In function ‘fec_enet_get_nextdesc’: drivers/net/ethernet/freescale/fec.c:215:18: error: invalid use of undefined type ‘struct bufdesc_ex’ drivers/net/ethernet/freescale/fec.c: In function ‘fec_enet_get_prevdesc’: drivers/net/ethernet/freescale/fec.c:224:18: error: invalid use of undefined type ‘struct bufdesc_ex’ drivers/net/ethernet/freescale/fec.c: In function ‘fec_enet_start_xmit’: drivers/net/ethernet/freescale/fec.c:286:37: error: arithmetic on pointer to an incomplete type drivers/net/ethernet/freescale/fec.c:287:13: error: arithmetic on pointer to an incomplete type drivers/net/ethernet/freescale/fec.c:324:7: error: dereferencing pointer to incomplete type etc.... Signed-off-by: Frank Li Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index c0f63be91ff7..f5390071efd0 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -97,6 +97,13 @@ struct bufdesc { unsigned short cbd_sc; /* Control and status info */ unsigned long cbd_bufaddr; /* Buffer address */ }; +#else +struct bufdesc { + unsigned short cbd_sc; /* Control and status info */ + unsigned short cbd_datlen; /* Data length */ + unsigned long cbd_bufaddr; /* Buffer address */ +}; +#endif struct bufdesc_ex { struct bufdesc desc; @@ -107,14 +114,6 @@ struct bufdesc_ex { unsigned short res0[4]; }; -#else -struct bufdesc { - unsigned short cbd_sc; /* Control and status info */ - unsigned short cbd_datlen; /* Data length */ - unsigned long cbd_bufaddr; /* Buffer address */ -}; -#endif - /* * The following definitions courtesy of commproc.h, which where * Copyright (c) 1997 Dan Malek (dmalek@jlc.net). -- cgit v1.2.3 From 0adcbaf78f6267baf4eecc201107d8f8ff3b200c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Mon, 11 Feb 2013 14:46:00 -0800 Subject: ARM: OMAP1: Fix build related to kgdb.h no longer including serial_8250.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 16559ae4 (kgdb: remove #include from kgdb.h) had a side effect of breaking omap1_defconfig build as some headers were included indirectly: arch/arm/mach-omap1/board-h2.c:249: error: ‘INT_KEYBOARD’ undeclared here (not in a function) ... This worked earlier as linux/serial_8250.h included linux/serial_core.h, via linux/serial_8250.h from linux/kgdb.h. Fix this by including the necessary headers directly. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/common.h | 2 ++ drivers/video/omap/lcd_ams_delta.c | 1 + drivers/video/omap/lcd_osk.c | 3 +++ 3 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/arch/arm/mach-omap1/common.h b/arch/arm/mach-omap1/common.h index fb18831e88aa..14f7e9920479 100644 --- a/arch/arm/mach-omap1/common.h +++ b/arch/arm/mach-omap1/common.h @@ -31,6 +31,8 @@ #include +#include + #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) void omap7xx_map_io(void); #else diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c index ed4cad87fbcd..4a5f2cd3d3bf 100644 --- a/drivers/video/omap/lcd_ams_delta.c +++ b/drivers/video/omap/lcd_ams_delta.c @@ -27,6 +27,7 @@ #include #include +#include #include #include "omapfb.h" diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c index 3aa62da89195..7fbe04bce0ed 100644 --- a/drivers/video/omap/lcd_osk.c +++ b/drivers/video/omap/lcd_osk.c @@ -24,7 +24,10 @@ #include #include + +#include #include + #include "omapfb.h" static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev) -- cgit v1.2.3 From 79e7654cae5a6d6cee333f0366023ecc3ff8abe0 Mon Sep 17 00:00:00 2001 From: Andrew Brownfield Date: Thu, 21 Feb 2013 14:01:50 -0500 Subject: ata_piix: Add MODULE_PARM_DESC to prefer_ms_hyperv In reference to the commit cd006086fa5d91414d8ff9ff2b78fbb593878e3c "ata_piix: defer disks to the Hyper-V drivers by default", this trivial patch adds a description to prefer_ms_hyperv. [rvrbovsk@redhat.com: MODULE_PARM_DESC() string formatting modified] Signed-off-by: Andrew Brownfield Signed-off-by: Radomir Vrbovsky Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index d2ba439cfe54..ffdd32d22602 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -1547,6 +1547,10 @@ static bool piix_broken_system_poweroff(struct pci_dev *pdev) static int prefer_ms_hyperv = 1; module_param(prefer_ms_hyperv, int, 0); +MODULE_PARM_DESC(prefer_ms_hyperv, + "Prefer Hyper-V paravirtualization drivers instead of ATA, " + "0 - Use ATA drivers, " + "1 (Default) - Use the paravirtualization drivers."); static void piix_ignore_devices_quirk(struct ata_host *host) { -- cgit v1.2.3 From efda332cb66d78d6fdf6f98e7b067480f43624f2 Mon Sep 17 00:00:00 2001 From: James Ralston Date: Thu, 21 Feb 2013 11:08:51 -0800 Subject: ahci: Add Device IDs for Intel Wellsburg PCH This patch adds the RAID-mode SATA Device IDs for the Intel Wellsburg PCH Signed-off-by: James Ralston Signed-off-by: Jeff Garzik --- drivers/ata/ahci.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index a99112cfd8b1..6a67b07de494 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -281,6 +281,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { { PCI_VDEVICE(INTEL, 0x1f37), board_ahci }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci }, /* Avoton RAID */ { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci }, /* Avoton RAID */ + { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */ + { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */ { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */ { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */ -- cgit v1.2.3 From c99cc9a2f19c29108ddb2e1ceb6f3baa536357d2 Mon Sep 17 00:00:00 2001 From: Syam Sidhardhan Date: Mon, 25 Feb 2013 04:44:07 +0530 Subject: sata_fsl: Remove redundant NULL check before kfree kfree on NULL pointer is a no-op. Signed-off-by: Syam Sidhardhan Signed-off-by: Jeff Garzik --- drivers/ata/sata_fsl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index 124b2c1d9c0b..608f82fed632 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c @@ -1511,8 +1511,7 @@ error_exit_with_cleanup: if (hcr_base) iounmap(hcr_base); - if (host_priv) - kfree(host_priv); + kfree(host_priv); return retval; } -- cgit v1.2.3 From dfd573644ce4ba1c9fbd625512bcfccf8c5ce7ff Mon Sep 17 00:00:00 2001 From: Sander Eikelenboom Date: Fri, 1 Mar 2013 12:16:42 +0100 Subject: libata-acpi.c: fix copy and paste mistake in ata_acpi_register_power_resource Fix a copy and paste mistake introduced in: commit bc9b6407bd6df3ab7189e5622816bbc11ae9d2d8 "ACPI / PM: Rework the handling of devices depending on power resources" Signed-off-by: Sander Eikelenboom Signed-off-by: Jeff Garzik --- drivers/ata/libata-acpi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c index 0ea1018280bd..cb3eab6d520f 100644 --- a/drivers/ata/libata-acpi.c +++ b/drivers/ata/libata-acpi.c @@ -1027,7 +1027,7 @@ static void ata_acpi_register_power_resource(struct ata_device *dev) handle = ata_dev_acpi_handle(dev); if (handle) - acpi_dev_pm_remove_dependent(handle, &sdev->sdev_gendev); + acpi_dev_pm_add_dependent(handle, &sdev->sdev_gendev); } static void ata_acpi_unregister_power_resource(struct ata_device *dev) -- cgit v1.2.3 From e189551bf74f098bde39cb8fb72a722bb7286f99 Mon Sep 17 00:00:00 2001 From: Aaron Lu Date: Sat, 2 Mar 2013 13:00:37 +0800 Subject: [libata] Avoid specialized TLA's in ZPODD's Kconfig ODD is not a common TLA for non-ATA people so they will get confused by its meaning when they are configuring the kernel. This patch fixed this problem by using ODD only after stating what it is. Signed-off-by: Aaron Lu Signed-off-by: Jeff Garzik --- drivers/ata/Kconfig | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 3e751b74615e..a5a3ebcbdd2c 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig @@ -59,15 +59,16 @@ config ATA_ACPI option libata.noacpi=1 config SATA_ZPODD - bool "SATA Zero Power ODD Support" + bool "SATA Zero Power Optical Disc Drive (ZPODD) support" depends on ATA_ACPI default n help - This option adds support for SATA ZPODD. It requires both - ODD and the platform support, and if enabled, will automatically - power on/off the ODD when certain condition is satisfied. This - does not impact user's experience of the ODD, only power is saved - when ODD is not in use(i.e. no disc inside). + This option adds support for SATA Zero Power Optical Disc + Drive (ZPODD). It requires both the ODD and the platform + support, and if enabled, will automatically power on/off the + ODD when certain condition is satisfied. This does not impact + end user's experience of the ODD, only power is saved when + the ODD is not in use (i.e. no disc inside). If unsure, say N. -- cgit v1.2.3 From b186affe0c9d39e4d3152cd34bffea8fe1fa17f4 Mon Sep 17 00:00:00 2001 From: Jingoo Han Date: Mon, 4 Mar 2013 17:34:42 +0900 Subject: pata_samsung_cf: 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: Jeff Garzik --- drivers/ata/pata_samsung_cf.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_samsung_cf.c b/drivers/ata/pata_samsung_cf.c index 70b0e01372b3..6ef27e98c508 100644 --- a/drivers/ata/pata_samsung_cf.c +++ b/drivers/ata/pata_samsung_cf.c @@ -661,18 +661,7 @@ static struct platform_driver pata_s3c_driver = { }, }; -static int __init pata_s3c_init(void) -{ - return platform_driver_probe(&pata_s3c_driver, pata_s3c_probe); -} - -static void __exit pata_s3c_exit(void) -{ - platform_driver_unregister(&pata_s3c_driver); -} - -module_init(pata_s3c_init); -module_exit(pata_s3c_exit); +module_platform_driver_probe(pata_s3c_driver, pata_s3c_probe); MODULE_AUTHOR("Abhilash Kesavan, "); MODULE_DESCRIPTION("low-level driver for Samsung PATA controller"); -- cgit v1.2.3 From f7f154f1246ccc5a0a7e9ce50932627d60a0c878 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 5 Mar 2013 10:07:08 +1030 Subject: hw_random: make buffer usable in scatterlist. virtio_rng feeds the randomness buffer handed by the core directly into the scatterlist, since commit bb347d98079a547e80bd4722dee1de61e4dca0e8. However, if CONFIG_HW_RANDOM=m, the static buffer isn't a linear address (at least on most archs). We could fix this in virtio_rng, but it's actually far easier to just do it in the core as virtio_rng would have to allocate a buffer every time (it doesn't know how much the core will want to read). Reported-by: Aurelien Jarno Tested-by: Aurelien Jarno Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/char/hw_random/core.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 1bafb40ec8a2..69ae5972713c 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c @@ -40,6 +40,7 @@ #include #include #include +#include #include @@ -52,8 +53,12 @@ static struct hwrng *current_rng; static LIST_HEAD(rng_list); static DEFINE_MUTEX(rng_mutex); static int data_avail; -static u8 rng_buffer[SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES] - __cacheline_aligned; +static u8 *rng_buffer; + +static size_t rng_buffer_size(void) +{ + return SMP_CACHE_BYTES < 32 ? 32 : SMP_CACHE_BYTES; +} static inline int hwrng_init(struct hwrng *rng) { @@ -116,7 +121,7 @@ static ssize_t rng_dev_read(struct file *filp, char __user *buf, if (!data_avail) { bytes_read = rng_get_data(current_rng, rng_buffer, - sizeof(rng_buffer), + rng_buffer_size(), !(filp->f_flags & O_NONBLOCK)); if (bytes_read < 0) { err = bytes_read; @@ -307,6 +312,14 @@ int hwrng_register(struct hwrng *rng) mutex_lock(&rng_mutex); + /* kmalloc makes this safe for virt_to_page() in virtio_rng.c */ + err = -ENOMEM; + if (!rng_buffer) { + rng_buffer = kmalloc(rng_buffer_size(), GFP_KERNEL); + if (!rng_buffer) + goto out_unlock; + } + /* Must not register two RNGs with the same name. */ err = -EEXIST; list_for_each_entry(tmp, &rng_list, list) { -- cgit v1.2.3 From 6402c796d3b4205d3d7296157956c5100a05d7d6 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 1 Mar 2013 10:50:08 -0500 Subject: USB: EHCI: work around silicon bug in Intel's EHCI controllers This patch (as1660) works around a hardware problem present in some (if not all) Intel EHCI controllers. After a QH has been unlinked from the async schedule and the corresponding IAA interrupt has occurred, the controller is not supposed access the QH and its qTDs. There certainly shouldn't be any more DMA writes to those structures. Nevertheless, Intel's controllers have been observed to perform a final writeback to the QH's overlay region and to the most recent qTD. For more information and a test program to determine whether this problem is present in a particular controller, see http://marc.info/?l=linux-usb&m=135492071812265&w=2 http://marc.info/?l=linux-usb&m=136182570800963&w=2 This patch works around the problem by always waiting for two IAA cycles when unlinking an async QH. The extra IAA delay gives the controller time to perform its final writeback. Surprisingly enough, the effects of this silicon bug have gone undetected until quite recently. More through luck than anything else, it hasn't caused any apparent problems. However, it does interact badly with the path that follows this one, so it needs to be addressed. This is the first part of a fix for the regression reported at: https://bugs.launchpad.net/bugs/1088733 Signed-off-by: Alan Stern Tested-by: Stephen Thirlwall CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 6 ++---- drivers/usb/host/ehci-q.c | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index b416a3fc9959..5726cb144abf 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -748,11 +748,9 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) /* guard against (alleged) silicon errata */ if (cmd & CMD_IAAD) ehci_dbg(ehci, "IAA with IAAD still set?\n"); - if (ehci->async_iaa) { + if (ehci->async_iaa) COUNT(ehci->stats.iaa); - end_unlink_async(ehci); - } else - ehci_dbg(ehci, "IAA with nothing unlinked?\n"); + end_unlink_async(ehci); } /* remote wakeup [4.3.1] */ diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index fd252f0cfb3a..7bf2b4eeb9ce 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1170,7 +1170,7 @@ static void single_unlink_async(struct ehci_hcd *ehci, struct ehci_qh *qh) struct ehci_qh *prev; /* Add to the end of the list of QHs waiting for the next IAAD */ - qh->qh_state = QH_STATE_UNLINK; + qh->qh_state = QH_STATE_UNLINK_WAIT; if (ehci->async_unlink) ehci->async_unlink_last->unlink_next = qh; else @@ -1213,9 +1213,19 @@ static void start_iaa_cycle(struct ehci_hcd *ehci, bool nested) /* Do only the first waiting QH (nVidia bug?) */ qh = ehci->async_unlink; - ehci->async_iaa = qh; - ehci->async_unlink = qh->unlink_next; - qh->unlink_next = NULL; + + /* + * Intel (?) bug: The HC can write back the overlay region + * even after the IAA interrupt occurs. In self-defense, + * always go through two IAA cycles for each QH. + */ + if (qh->qh_state == QH_STATE_UNLINK_WAIT) { + qh->qh_state = QH_STATE_UNLINK; + } else { + ehci->async_iaa = qh; + ehci->async_unlink = qh->unlink_next; + qh->unlink_next = NULL; + } /* Make sure the unlinks are all visible to the hardware */ wmb(); -- cgit v1.2.3 From feca7746d5d9e84b105a613b7f3b6ad00d327372 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 1 Mar 2013 10:51:15 -0500 Subject: USB: EHCI: don't check DMA values in QH overlays This patch (as1661) fixes a rather obscure bug in ehci-hcd. In a couple of places, the driver compares the DMA address stored in a QH's overlay region with the address of a particular qTD, in order to see whether that qTD is the one currently being processed by the hardware. (If it is then the status in the QH's overlay region is more up-to-date than the status in the qTD, and if it isn't then the overlay's value needs to be adjusted when the QH is added back to the active schedule.) However, DMA address in the overlay region isn't always valid. It sometimes will contain a stale value, which may happen by coincidence to be equal to a qTD's DMA address. Instead of checking the DMA address, we should check whether the overlay region is active and valid. The patch tests the ACTIVE bit in the overlay, and clears this bit when the overlay becomes invalid (which happens when the currently-executing URB is unlinked). This is the second part of a fix for the regression reported at: https://bugs.launchpad.net/bugs/1088733 Signed-off-by: Alan Stern Reported-by: Joseph Salisbury Reported-and-tested-by: Stephen Thirlwall CC: Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-q.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 7bf2b4eeb9ce..5464665f0b6a 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -135,7 +135,7 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) * qtd is updated in qh_completions(). Update the QH * overlay here. */ - if (cpu_to_hc32(ehci, qtd->qtd_dma) == qh->hw->hw_current) { + if (qh->hw->hw_token & ACTIVE_BIT(ehci)) { qh->hw->hw_qtd_next = qtd->hw_next; qtd = NULL; } @@ -449,11 +449,19 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) else if (last_status == -EINPROGRESS && !urb->unlinked) continue; - /* qh unlinked; token in overlay may be most current */ - if (state == QH_STATE_IDLE - && cpu_to_hc32(ehci, qtd->qtd_dma) - == hw->hw_current) { + /* + * If this was the active qtd when the qh was unlinked + * and the overlay's token is active, then the overlay + * hasn't been written back to the qtd yet so use its + * token instead of the qtd's. After the qtd is + * processed and removed, the overlay won't be valid + * any more. + */ + if (state == QH_STATE_IDLE && + qh->qtd_list.next == &qtd->qtd_list && + (hw->hw_token & ACTIVE_BIT(ehci))) { token = hc32_to_cpu(ehci, hw->hw_token); + hw->hw_token &= ~ACTIVE_BIT(ehci); /* An unlink may leave an incomplete * async transaction in the TT buffer. -- cgit v1.2.3 From 91bdf0d0c48c9254fb73037bfb8ee1777093225b Mon Sep 17 00:00:00 2001 From: Javi Merino Date: Tue, 19 Feb 2013 13:52:22 +0000 Subject: irqchip: fix typo when moving gic_raise_softirq() In b1cffebf (ARM: GIC: remove direct use of gic_raise_softirq) gic_raise_softirq() was moved inside arch/arm/common/gic.c but in the process it reverted by mistake a change to that function made by 384a290 (ARM: gic: use a private mapping for CPU target interfaces). This breaks multicluster systems on ARM. This patch fixes the typo. Signed-off-by: Javi Merino Acked-by: Rob Herring Signed-off-by: Olof Johansson --- drivers/irqchip/irq-gic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c index 644d72468423..a32e0d5aa45f 100644 --- a/drivers/irqchip/irq-gic.c +++ b/drivers/irqchip/irq-gic.c @@ -648,7 +648,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) /* Convert our logical CPU mask into a physical one. */ for_each_cpu(cpu, mask) - map |= 1 << cpu_logical_map(cpu); + map |= gic_cpu_map[cpu]; /* * Ensure that stores to Normal memory are visible to the -- cgit v1.2.3 From 984b839337da1eb7b4a4fb50e24cf28c2b473862 Mon Sep 17 00:00:00 2001 From: Prashant Gaikwad Date: Fri, 1 Mar 2013 11:32:25 -0700 Subject: clk: Tegra: Remove duplicate smp_twd clock Remove duplicate smp_twd clocks as these clocks are accessed using DT now. Signed-off-by: Prashant Gaikwad Signed-off-by: Stephen Warren Signed-off-by: Olof Johansson --- drivers/clk/tegra/clk-tegra20.c | 1 - drivers/clk/tegra/clk-tegra30.c | 1 - 2 files changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c index 143ce1f899ad..1e2de7305362 100644 --- a/drivers/clk/tegra/clk-tegra20.c +++ b/drivers/clk/tegra/clk-tegra20.c @@ -1292,7 +1292,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { TEGRA_CLK_DUPLICATE(usbd, "tegra-ehci.0", NULL), TEGRA_CLK_DUPLICATE(usbd, "tegra-otg", NULL), TEGRA_CLK_DUPLICATE(cclk, NULL, "cpu"), - TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL), TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* Must be the last entry */ }; diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c index 32c61cb6d0bb..ba6f51bc9f3b 100644 --- a/drivers/clk/tegra/clk-tegra30.c +++ b/drivers/clk/tegra/clk-tegra30.c @@ -1931,7 +1931,6 @@ static struct tegra_clk_duplicate tegra_clk_duplicates[] = { TEGRA_CLK_DUPLICATE(cml1, "tegra_sata_cml", NULL), TEGRA_CLK_DUPLICATE(cml0, "tegra_pcie", "cml"), TEGRA_CLK_DUPLICATE(pciex, "tegra_pcie", "pciex"), - TEGRA_CLK_DUPLICATE(twd, "smp_twd", NULL), TEGRA_CLK_DUPLICATE(vcp, "nvavp", "vcp"), TEGRA_CLK_DUPLICATE(clk_max, NULL, NULL), /* MUST be the last entry */ }; -- cgit v1.2.3 From 9276dfd27897a0b29d8b5814f39a1f82f56b6b6b Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Mon, 25 Feb 2013 17:43:25 +0000 Subject: drivers/tty/hvc: Use strlcpy instead of strncpy when strlen pi->location_code is larger than HVCS_CLC_LENGTH + 1, original implementation can not let hvcsd->p_location_code NUL terminated. so need fix it (also can simplify the code) Signed-off-by: Chen Gang Signed-off-by: Benjamin Herrenschmidt --- drivers/tty/hvc/hvcs.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/hvc/hvcs.c b/drivers/tty/hvc/hvcs.c index 1956593ee89d..81e939e90c4c 100644 --- a/drivers/tty/hvc/hvcs.c +++ b/drivers/tty/hvc/hvcs.c @@ -881,17 +881,12 @@ static struct vio_driver hvcs_vio_driver = { /* Only called from hvcs_get_pi please */ static void hvcs_set_pi(struct hvcs_partner_info *pi, struct hvcs_struct *hvcsd) { - int clclength; - hvcsd->p_unit_address = pi->unit_address; hvcsd->p_partition_ID = pi->partition_ID; - clclength = strlen(&pi->location_code[0]); - if (clclength > HVCS_CLC_LENGTH) - clclength = HVCS_CLC_LENGTH; /* copy the null-term char too */ - strncpy(&hvcsd->p_location_code[0], - &pi->location_code[0], clclength + 1); + strlcpy(&hvcsd->p_location_code[0], + &pi->location_code[0], sizeof(hvcsd->p_location_code)); } /* -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From e08f626b33eb636dbf38b21618ab32b7fd8e1ec4 Mon Sep 17 00:00:00 2001 From: Bruce Allan Date: Wed, 20 Feb 2013 03:06:34 +0000 Subject: e1000e: workaround DMA unit hang on I218 At 1000Mbps link speed, one of the MAC's internal clocks can be stopped for up to 4us when entering K1 (a power mode of the MAC-PHY interconnect). If the MAC is waiting for completion indications for 2 DMA write requests into Host memory (e.g. descriptor writeback or Rx packet writing) and the indications occur while the clock is stopped, both indications will be missed by the MAC causing the MAC to wait for the completion indications and be unable to generate further DMA write requests. This results in an apparent hardware hang. Work-around the issue by disabling the de-assertion of the clock request when 1000Mbps link is acquired (K1 must be disabled while doing this). Signed-off-by: Bruce Allan Tested-by: Jeff Pieper Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ich8lan.c | 71 ++++++++++++++++++++++++++++- drivers/net/ethernet/intel/e1000e/ich8lan.h | 2 + drivers/net/ethernet/intel/e1000e/regs.h | 1 + 3 files changed, 73 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index dff7bff8b8e0..121a865c7fbd 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c @@ -781,6 +781,59 @@ release: return ret_val; } +/** + * e1000_k1_workaround_lpt_lp - K1 workaround on Lynxpoint-LP + * @hw: pointer to the HW structure + * @link: link up bool flag + * + * When K1 is enabled for 1Gbps, the MAC can miss 2 DMA completion indications + * preventing further DMA write requests. Workaround the issue by disabling + * the de-assertion of the clock request when in 1Gpbs mode. + **/ +static s32 e1000_k1_workaround_lpt_lp(struct e1000_hw *hw, bool link) +{ + u32 fextnvm6 = er32(FEXTNVM6); + s32 ret_val = 0; + + if (link && (er32(STATUS) & E1000_STATUS_SPEED_1000)) { + u16 kmrn_reg; + + ret_val = hw->phy.ops.acquire(hw); + if (ret_val) + return ret_val; + + ret_val = + e1000e_read_kmrn_reg_locked(hw, E1000_KMRNCTRLSTA_K1_CONFIG, + &kmrn_reg); + if (ret_val) + goto release; + + ret_val = + e1000e_write_kmrn_reg_locked(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + kmrn_reg & + ~E1000_KMRNCTRLSTA_K1_ENABLE); + if (ret_val) + goto release; + + usleep_range(10, 20); + + ew32(FEXTNVM6, fextnvm6 | E1000_FEXTNVM6_REQ_PLL_CLK); + + ret_val = + e1000e_write_kmrn_reg_locked(hw, + E1000_KMRNCTRLSTA_K1_CONFIG, + kmrn_reg); +release: + hw->phy.ops.release(hw); + } else { + /* clear FEXTNVM6 bit 8 on link down or 10/100 */ + ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); + } + + return ret_val; +} + /** * e1000_check_for_copper_link_ich8lan - Check for link (Copper) * @hw: pointer to the HW structure @@ -818,6 +871,14 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) return ret_val; } + /* Work-around I218 hang issue */ + if ((hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_LM) || + (hw->adapter->pdev->device == E1000_DEV_ID_PCH_LPTLP_I218_V)) { + ret_val = e1000_k1_workaround_lpt_lp(hw, link); + if (ret_val) + return ret_val; + } + /* Clear link partner's EEE ability */ hw->dev_spec.ich8lan.eee_lp_ability = 0; @@ -3954,8 +4015,16 @@ void e1000_suspend_workarounds_ich8lan(struct e1000_hw *hw) phy_ctrl = er32(PHY_CTRL); phy_ctrl |= E1000_PHY_CTRL_GBE_DISABLE; + if (hw->phy.type == e1000_phy_i217) { - u16 phy_reg; + u16 phy_reg, device_id = hw->adapter->pdev->device; + + if ((device_id == E1000_DEV_ID_PCH_LPTLP_I218_LM) || + (device_id == E1000_DEV_ID_PCH_LPTLP_I218_V)) { + u32 fextnvm6 = er32(FEXTNVM6); + + ew32(FEXTNVM6, fextnvm6 & ~E1000_FEXTNVM6_REQ_PLL_CLK); + } ret_val = hw->phy.ops.acquire(hw); if (ret_val) diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index b6d3174d7d2d..8bf4655c2e17 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h @@ -92,6 +92,8 @@ #define E1000_FEXTNVM4_BEACON_DURATION_8USEC 0x7 #define E1000_FEXTNVM4_BEACON_DURATION_16USEC 0x3 +#define E1000_FEXTNVM6_REQ_PLL_CLK 0x00000100 + #define PCIE_ICH8_SNOOP_ALL PCIE_NO_SNOOP_ALL #define E1000_ICH_RAR_ENTRIES 7 diff --git a/drivers/net/ethernet/intel/e1000e/regs.h b/drivers/net/ethernet/intel/e1000e/regs.h index 794fe1497666..a7e6a3e37257 100644 --- a/drivers/net/ethernet/intel/e1000e/regs.h +++ b/drivers/net/ethernet/intel/e1000e/regs.h @@ -42,6 +42,7 @@ #define E1000_FEXTNVM 0x00028 /* Future Extended NVM - RW */ #define E1000_FEXTNVM3 0x0003C /* Future Extended NVM 3 - RW */ #define E1000_FEXTNVM4 0x00024 /* Future Extended NVM 4 - RW */ +#define E1000_FEXTNVM6 0x00010 /* Future Extended NVM 6 - RW */ #define E1000_FEXTNVM7 0x000E4 /* Future Extended NVM 7 - RW */ #define E1000_FCT 0x00030 /* Flow Control Type - RW */ #define E1000_VET 0x00038 /* VLAN Ether Type - RW */ -- cgit v1.2.3 From 0920a48719f1ceefc909387a64f97563848c7854 Mon Sep 17 00:00:00 2001 From: Stéphane Marchesin Date: Tue, 29 Jan 2013 19:41:59 -0800 Subject: drm/i915: Increase the RC6p threshold. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This increases GEN6_RC6p_THRESHOLD from 100000 to 150000. For some reason this avoids the gen6_gt_check_fifodbg.isra warnings and associated GPU lockups, which makes my ivy bridge machine stable. Signed-off-by: Stéphane Marchesin Acked-by: Jesse Barnes Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_pm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 61fee7fcdc2c..a1794c6df1bf 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -2574,7 +2574,7 @@ static void gen6_enable_rps(struct drm_device *dev) I915_WRITE(GEN6_RC_SLEEP, 0); I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); I915_WRITE(GEN6_RC6_THRESHOLD, 50000); - I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); + I915_WRITE(GEN6_RC6p_THRESHOLD, 150000); I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ /* Check if we are enabling RC6 */ -- cgit v1.2.3 From e4f7dbb17e797d922d72567f37de3735722034ba Mon Sep 17 00:00:00 2001 From: Alexander Duyck Date: Thu, 21 Feb 2013 03:08:50 +0000 Subject: igb: Drop BUILD_BUG_ON check from igb_build_rx_buffer On s390 the igb driver was throwing a build error due to the fact that a frame built using build_skb would be larger than 2K. Since this is not likely to change at any point in the future we are better off just dropping the check since we already had a check in igb_set_rx_buffer_len that will just disable the usage of build_skb anyway. Signed-off-by: Alexander Duyck Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb_main.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index ed79a1c53b59..4d53a17959fa 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -6227,13 +6227,6 @@ static struct sk_buff *igb_build_rx_buffer(struct igb_ring *rx_ring, /* If we spanned a buffer we have a huge mess so test for it */ BUG_ON(unlikely(!igb_test_staterr(rx_desc, E1000_RXD_STAT_EOP))); - /* Guarantee this function can be used by verifying buffer sizes */ - BUILD_BUG_ON(SKB_WITH_OVERHEAD(IGB_RX_BUFSZ) < (NET_SKB_PAD + - NET_IP_ALIGN + - IGB_TS_HDR_LEN + - ETH_FRAME_LEN + - ETH_FCS_LEN)); - rx_buffer = &rx_ring->rx_buffer_info[rx_ring->next_to_clean]; page = rx_buffer->page; prefetchw(page); -- cgit v1.2.3 From ed65bdd8c0086d69948e6380dba0cc279a6906de Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 6 Feb 2013 03:35:27 +0000 Subject: igb: Fix link setup for I210 devices This patch changes the setup copper link function to use a switch statement for the PHY id's available for the given PHY types. It also adds a case for the I210 PHY id, so the appropriate setup link function is called for it. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/e1000_82575.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 84e7e0909def..b64542acfa34 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c @@ -1361,11 +1361,16 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw) switch (hw->phy.type) { case e1000_phy_i210: case e1000_phy_m88: - if (hw->phy.id == I347AT4_E_PHY_ID || - hw->phy.id == M88E1112_E_PHY_ID) + switch (hw->phy.id) { + case I347AT4_E_PHY_ID: + case M88E1112_E_PHY_ID: + case I210_I_PHY_ID: ret_val = igb_copper_link_setup_m88_gen2(hw); - else + break; + default: ret_val = igb_copper_link_setup_m88(hw); + break; + } break; case e1000_phy_igp_3: ret_val = igb_copper_link_setup_igp(hw); -- cgit v1.2.3 From 15239099d7a7a9ecdc1ccb5b187ae4cda5488ff9 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Tue, 5 Mar 2013 09:50:58 +0100 Subject: drm/i915: enable irqs earlier when resuming We need it to restore the ilk rc6 context, since the gpu wait no requires interrupts. But in general having interrupts around should help in code sanity, since more and more stuff is interrupt driven. This regression has been introduced in commit 3e9605018ab3e333d51cc90fccfde2031886763b Author: Chris Wilson Date: Tue Nov 27 16:22:54 2012 +0000 drm/i915: Rearrange code to only have a single method for waiting upon the ring Like in the driver load code we need to make sure that hotplug interrupts don't cause havoc with our modeset state, hence block them with the existing infrastructure. Again we ignore races where we might loose hotplug interrupts ... Note that the driver load part of the regression has already been fixed in commit 52d7ecedac3f96fb562cb482c139015372728638 Author: Daniel Vetter Date: Sat Dec 1 21:03:22 2012 +0100 drm/i915: reorder setup sequence to have irqs for output setup v2: Add a note to the commit message about which patch fixed the driver load part of the regression. Stable kernels need to backport both patches. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=54691 Cc: stable@vger.kernel.org (for 3.8 only, plese backport 52d7ecedac3f96fb5 first) Cc: Chris Wilson Cc: Mika Kuoppala Reported-and-Tested-by: Ilya Tumaykin Reviewed-by: Chris wilson (v1) Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2c5ee965e473..0a8eceb75902 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -495,6 +495,7 @@ static int i915_drm_freeze(struct drm_device *dev) intel_modeset_disable(dev); drm_irq_uninstall(dev); + dev_priv->enable_hotplug_processing = false; } i915_save_state(dev); @@ -568,10 +569,20 @@ static int __i915_drm_thaw(struct drm_device *dev) error = i915_gem_init_hw(dev); mutex_unlock(&dev->struct_mutex); + /* We need working interrupts for modeset enabling ... */ + drm_irq_install(dev); + intel_modeset_init_hw(dev); intel_modeset_setup_hw_state(dev, false); - drm_irq_install(dev); + + /* + * ... but also need to make sure that hotplug processing + * doesn't cause havoc. Like in the driver load code we don't + * bother with the tiny race here where we might loose hotplug + * notifications. + * */ intel_hpd_init(dev); + dev_priv->enable_hotplug_processing = true; } intel_opregion_init(dev); -- cgit v1.2.3 From 603e86fa39cd48edba5ee8a4d19637bd41e2a8bf Mon Sep 17 00:00:00 2001 From: Carolyn Wyborny Date: Wed, 20 Feb 2013 07:40:55 +0000 Subject: igb: Fix for lockdep issue in igb_get_i2c_client This patch fixes a lockdep warning in igb_get_i2c_client by refactoring the initialization and usage of the i2c_client completely. There is no on the fly allocation of the single client needed today. Signed-off-by: Carolyn Wyborny Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/igb/igb.h | 2 +- drivers/net/ethernet/intel/igb/igb_hwmon.c | 14 ++++++ drivers/net/ethernet/intel/igb/igb_main.c | 69 +----------------------------- 3 files changed, 17 insertions(+), 68 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h index d27edbc63923..25151401c2ab 100644 --- a/drivers/net/ethernet/intel/igb/igb.h +++ b/drivers/net/ethernet/intel/igb/igb.h @@ -447,7 +447,7 @@ struct igb_adapter { #endif struct i2c_algo_bit_data i2c_algo; struct i2c_adapter i2c_adap; - struct igb_i2c_client_list *i2c_clients; + struct i2c_client *i2c_client; }; #define IGB_FLAG_HAS_MSI (1 << 0) diff --git a/drivers/net/ethernet/intel/igb/igb_hwmon.c b/drivers/net/ethernet/intel/igb/igb_hwmon.c index 0a9b073d0b03..4623502054d5 100644 --- a/drivers/net/ethernet/intel/igb/igb_hwmon.c +++ b/drivers/net/ethernet/intel/igb/igb_hwmon.c @@ -39,6 +39,10 @@ #include #ifdef CONFIG_IGB_HWMON +struct i2c_board_info i350_sensor_info = { + I2C_BOARD_INFO("i350bb", (0Xf8 >> 1)), +}; + /* hwmon callback functions */ static ssize_t igb_hwmon_show_location(struct device *dev, struct device_attribute *attr, @@ -188,6 +192,7 @@ int igb_sysfs_init(struct igb_adapter *adapter) unsigned int i; int n_attrs; int rc = 0; + struct i2c_client *client = NULL; /* If this method isn't defined we don't support thermals */ if (adapter->hw.mac.ops.init_thermal_sensor_thresh == NULL) @@ -198,6 +203,15 @@ int igb_sysfs_init(struct igb_adapter *adapter) if (rc) goto exit; + /* init i2c_client */ + client = i2c_new_device(&adapter->i2c_adap, &i350_sensor_info); + if (client == NULL) { + dev_info(&adapter->pdev->dev, + "Failed to create new i2c device..\n"); + goto exit; + } + adapter->i2c_client = client; + /* Allocation space for max attributes * max num sensors * values (loc, temp, max, caution) */ diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 4d53a17959fa..4dbd62968c7a 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c @@ -1923,10 +1923,6 @@ void igb_set_fw_version(struct igb_adapter *adapter) return; } -static const struct i2c_board_info i350_sensor_info = { - I2C_BOARD_INFO("i350bb", 0Xf8), -}; - /* igb_init_i2c - Init I2C interface * @adapter: pointer to adapter structure * @@ -7717,67 +7713,6 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) } } -static DEFINE_SPINLOCK(i2c_clients_lock); - -/* igb_get_i2c_client - returns matching client - * in adapters's client list. - * @adapter: adapter struct - * @dev_addr: device address of i2c needed. - */ -static struct i2c_client * -igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr) -{ - ulong flags; - struct igb_i2c_client_list *client_list; - struct i2c_client *client = NULL; - struct i2c_board_info client_info = { - I2C_BOARD_INFO("igb", 0x00), - }; - - spin_lock_irqsave(&i2c_clients_lock, flags); - client_list = adapter->i2c_clients; - - /* See if we already have an i2c_client */ - while (client_list) { - if (client_list->client->addr == (dev_addr >> 1)) { - client = client_list->client; - goto exit; - } else { - client_list = client_list->next; - } - } - - /* no client_list found, create a new one */ - client_list = kzalloc(sizeof(*client_list), GFP_ATOMIC); - if (client_list == NULL) - goto exit; - - /* dev_addr passed to us is left-shifted by 1 bit - * i2c_new_device call expects it to be flush to the right. - */ - client_info.addr = dev_addr >> 1; - client_info.platform_data = adapter; - client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info); - if (client_list->client == NULL) { - dev_info(&adapter->pdev->dev, - "Failed to create new i2c device..\n"); - goto err_no_client; - } - - /* insert new client at head of list */ - client_list->next = adapter->i2c_clients; - adapter->i2c_clients = client_list; - - client = client_list->client; - goto exit; - -err_no_client: - kfree(client_list); -exit: - spin_unlock_irqrestore(&i2c_clients_lock, flags); - return client; -} - /* igb_read_i2c_byte - Reads 8 bit word over I2C * @hw: pointer to hardware structure * @byte_offset: byte offset to read @@ -7791,7 +7726,7 @@ s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr, u8 *data) { struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); - struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); + struct i2c_client *this_client = adapter->i2c_client; s32 status; u16 swfw_mask = 0; @@ -7828,7 +7763,7 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr, u8 data) { struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); - struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); + struct i2c_client *this_client = adapter->i2c_client; s32 status; u16 swfw_mask = E1000_SWFW_PHY0_SM; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From fbe2d3616cee37418d832b30130811888c5aaf34 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Thu, 21 Feb 2013 21:44:17 -0800 Subject: EDAC: Make sysfs functions static Fixes lots of sparse warnings here. Signed-off-by: Stephen Hemminger Signed-off-by: Borislav Petkov --- drivers/edac/edac_mc_sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 4f4b6137d74e..0cbf670efa23 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -143,7 +143,7 @@ static const char *edac_caps[] = { * and the per-dimm/per-rank one */ #define DEVICE_ATTR_LEGACY(_name, _mode, _show, _store) \ - struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store) + static struct device_attribute dev_attr_legacy_##_name = __ATTR(_name, _mode, _show, _store) struct dev_ch_attribute { struct device_attribute attr; -- cgit v1.2.3 From 43febb27dcdaf9a15e2f362a6d09b0f191c4dcea Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 4 Mar 2013 16:52:38 -0600 Subject: usb: gadget: composite: fix kernel-doc warnings A few trivial fixes for composite driver: Warning(include/linux/usb/composite.h:165): No description found for parameter 'fs_descriptors' Warning(include/linux/usb/composite.h:165): Excess struct/union/enum/typedef member 'descriptors' description in 'usb_function' Warning(include/linux/usb/composite.h:321): No description found for parameter 'gadget_driver' Warning(drivers/usb/gadget/composite.c:1777): Excess function parameter 'bind' description in 'usb_composite_probe' Cc: Greg Kroah-Hartman Cc: Jiri Kosina Cc: linux-usb@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Nishanth Menon Signed-off-by: Felipe Balbi --- drivers/usb/gadget/composite.c | 5 +---- include/linux/usb/composite.h | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 7c821de8ce3d..c0d62b278610 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c @@ -1757,10 +1757,7 @@ static const struct usb_gadget_driver composite_driver_template = { /** * 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 diff --git a/include/linux/usb/composite.h b/include/linux/usb/composite.h index 3c671c1b37f6..8860594d6364 100644 --- a/include/linux/usb/composite.h +++ b/include/linux/usb/composite.h @@ -60,7 +60,7 @@ struct usb_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 + * @fs_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 @@ -290,6 +290,7 @@ enum { * after function notifications * @resume: Notifies configuration when the host restarts USB traffic, * before function notifications + * @gadget_driver: Gadget driver controlling this driver * * Devices default to reporting self powered operation. Devices which rely * on bus powered operation should report this in their @bind method. -- cgit v1.2.3 From 341a71c790529140fc5f8833f893324f6b5261cc Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 5 Mar 2013 13:18:49 +0200 Subject: usb: musb: remove all 'select' from Kconfig those are quite unnecessary, the only thing we need to be careful about is USB_OTG_UTILS which get properly selected by PHY drivers. For now, MUSB will select only USB_OTG_UTILS until we add stubs for the cases when PHY layer isn't enabled. Signed-off-by: Felipe Balbi --- drivers/usb/musb/Kconfig | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 2f7d84af6650..05e51432dd2f 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig @@ -7,9 +7,6 @@ config USB_MUSB_HDRC tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' depends on USB && USB_GADGET - select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) - select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) - select OMAP_CONTROL_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA select USB_OTG_UTILS help Say Y here if your system has a dual role high speed USB @@ -49,8 +46,6 @@ config USB_MUSB_TUSB6010 config USB_MUSB_OMAP2PLUS tristate "OMAP2430 and onwards" depends on ARCH_OMAP2PLUS - select TWL4030_USB if MACH_OMAP_3430SDP - select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA config USB_MUSB_AM35X tristate "AM35x" -- cgit v1.2.3 From e574d5708156585ee506b7f914ed4a55a319d294 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Tue, 5 Mar 2013 13:25:36 +0200 Subject: usb: musb: fix compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When running 100 randconfig iterations, I found the following warning: drivers/usb/musb/musb_core.c: In function ‘musb_init_controller’: drivers/usb/musb/musb_core.c:1981:1: warning: label ‘fail5’ defined \ but not used [-Wunused-label] this patch fixes it by removing the unnecessary ifdef CONFIG_SYSFS. 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 60b41cc28da4..13382e053d59 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1968,11 +1968,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl) if (status < 0) goto fail4; -#ifdef CONFIG_SYSFS status = sysfs_create_group(&musb->controller->kobj, &musb_attr_group); if (status) goto fail5; -#endif pm_runtime_put(musb->controller); -- cgit v1.2.3 From f8c4b0e73b636fe06e8283f29905c2e60ed66fa1 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 5 Mar 2013 13:04:23 +0200 Subject: usb: musb: omap2430: fix omap_musb_mailbox glue check again Commit 80ab72e1 (usb: musb: omap2430: fix the readiness check in omap_musb_mailbox) made the check incorrect, as we will lose the glue/link status during the normal built-in probe order (twl4030_usb is probed after musb omap2430, but before musb core is ready). As a result, if you boot with USB cable on and load g_ether, the connection does not work as the code thinks the cable is off and the phy gets powered down immediately. This is a major regression in 3.9-rc1. So the proper check should be: exit if _glue is NULL, but if it's initialized we memorize the status, and then check if the musb core is ready. Signed-off-by: Aaro Koskinen Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 1762354fe793..2a39c110d3d5 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -237,9 +237,13 @@ void omap_musb_mailbox(enum omap_musb_vbus_id_status status) { struct omap2430_glue *glue = _glue; - if (glue && glue_to_musb(glue)) { - glue->status = status; - } else { + if (!glue) { + pr_err("%s: musb core is not yet initialized\n", __func__); + return; + } + glue->status = status; + + if (!glue_to_musb(glue)) { pr_err("%s: musb core is not yet ready\n", __func__); return; } -- cgit v1.2.3 From 4b58ed11c681c0779c330f1aa5307b594943b683 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Tue, 5 Mar 2013 13:04:24 +0200 Subject: usb: musb: omap2430: fix sparse warning Fix the following sparse warning: drivers/usb/musb/omap2430.c:54:33: warning: symbol '_glue' was not \ declared. Should it be static? Signed-off-by: Aaro Koskinen Signed-off-by: Felipe Balbi --- drivers/usb/musb/omap2430.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c index 2a39c110d3d5..1a42a458f2c4 100644 --- a/drivers/usb/musb/omap2430.c +++ b/drivers/usb/musb/omap2430.c @@ -51,7 +51,7 @@ struct omap2430_glue { }; #define glue_to_musb(g) platform_get_drvdata(g->musb) -struct omap2430_glue *_glue; +static struct omap2430_glue *_glue; static struct timer_list musb_idle_timer; -- cgit v1.2.3 From 852afe99fc1c2d2b1376e49f128a3b929e811f2d Mon Sep 17 00:00:00 2001 From: Denis CIOCCA Date: Tue, 26 Feb 2013 10:43:00 +0000 Subject: iio:common:st_sensors fixed all warning messages about uninitialized variables Signed-off-by: Denis Ciocca Reported-by: Fengguang Wu Signed-off-by: Jonathan Cameron --- drivers/iio/common/st_sensors/st_sensors_core.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c index 0198324a8b0c..bd33473f8e38 100644 --- a/drivers/iio/common/st_sensors/st_sensors_core.c +++ b/drivers/iio/common/st_sensors/st_sensors_core.c @@ -62,7 +62,7 @@ st_sensors_match_odr_error: int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr) { int err; - struct st_sensor_odr_avl odr_out; + struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); err = st_sensors_match_odr(sdata->sensor, odr, &odr_out); @@ -114,7 +114,7 @@ st_sensors_match_odr_error: static int st_sensors_set_fullscale(struct iio_dev *indio_dev, unsigned int fs) { - int err, i; + int err, i = 0; struct st_sensor_data *sdata = iio_priv(indio_dev); err = st_sensors_match_fs(sdata->sensor, fs, &i); @@ -139,14 +139,13 @@ st_accel_set_fullscale_error: int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable) { - bool found; u8 tmp_value; int err = -EINVAL; - struct st_sensor_odr_avl odr_out; + bool found = false; + struct st_sensor_odr_avl odr_out = {0, 0}; struct st_sensor_data *sdata = iio_priv(indio_dev); if (enable) { - found = false; tmp_value = sdata->sensor->pw.value_on; if ((sdata->sensor->odr.addr == sdata->sensor->pw.addr) && (sdata->sensor->odr.mask == sdata->sensor->pw.mask)) { -- cgit v1.2.3 From 44498aea293b37af1d463acd9658cdce1ecdf427 Mon Sep 17 00:00:00 2001 From: Paulo Zanoni Date: Fri, 22 Feb 2013 17:05:28 -0300 Subject: drm/i915: also disable south interrupts when handling them From the docs: "IIR can queue up to two interrupt events. When the IIR is cleared, it will set itself again after one clock if a second event was stored." "Only the rising edge of the PCH Display interrupt will cause the North Display IIR (DEIIR) PCH Display Interrupt even bit to be set, so all PCH Display Interrupts, including back to back interrupts, must be cleared before a new PCH Display interrupt can cause DEIIR to be set". The current code works fine because we don't get many interrupts, but if we enable the PCH FIFO underrun interrupts we'll start getting so many interrupts that at some point new PCH interrupts won't cause DEIIR to be set. The initial implementation I tried was to turn the code that checks SDEIIR into a loop, but we can still get interrupts even after the loop is done (and before the irq handler finishes), so we have to either disable the interrupts or mask them. In the end I concluded that just disabling the PCH interrupts is enough, you don't even need the loop, so this is what this patch implements. I've tested it and it passes the 2 "PCH FIFO underrun interrupt storms" I can reproduce: the "ironlake_crtc_disable" case and the "wrong watermarks" case. In other words, here's how to reproduce the problem fixed by this patch: 1 - Enable PCH FIFO underrun interrupts (SERR_INT on SNB+) 2 - Boot the machine 3 - While booting we'll get tons of PCH FIFO underrun interrupts 4 - Plug a new monitor 5 - Run xrandr, notice it won't detect the new monitor 6 - Read SDEIIR and notice it's not 0 while DEIIR is 0 Q: Can't we just clear DEIIR before SDEIIR? A: It doesn't work. SDEIIR has to be completely cleared (including the interrupts stored on its back queue) before it can flip DEIIR's bit to 1 again, and even while you're clearing it you'll be getting more and more interrupts. Q: Why does it work by just disabling+enabling the south interrupts? A: Because when we re-enable them, if there's something on the SDEIIR register (maybe an interrupt stored on the queue), the re-enabling will make DEIIR's bit flip to 1, and since we'll already have interrupts enabled we'll get another interrupt, then run our irq handler again to process the "back" interrupts. v2: Even bigger commit message, added code comments. Note that this fixes missed dp aux irqs which have been reported for 3.9-rc1. This regression has been introduced by switching to irq-driven dp aux transactions with commit 9ee32fea5fe810ec06af3a15e4c65478de56d4f5 Author: Daniel Vetter Date: Sat Dec 1 13:53:48 2012 +0100 drm/i915: irq-drive the dp aux communication References: http://www.mail-archive.com/intel-gfx@lists.freedesktop.org/msg18588.html References: https://lkml.org/lkml/2013/2/26/769 Tested-by: Imre Deak Reported-by: Sedat Dilek Reported-by: Linus Torvalds Signed-off-by: Paulo Zanoni [danvet: Pimp commit message with references for the dp aux irq timeout regression this fixes.] Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_irq.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2cd97d1cc920..3c7bb0410b51 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -701,7 +701,7 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - u32 de_iir, gt_iir, de_ier, pm_iir; + u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier; irqreturn_t ret = IRQ_NONE; int i; @@ -711,6 +711,15 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) de_ier = I915_READ(DEIER); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); + /* Disable south interrupts. We'll only write to SDEIIR once, so further + * interrupts will will be stored on its back queue, and then we'll be + * able to process them after we restore SDEIER (as soon as we restore + * it, we'll get an interrupt if SDEIIR still has something to process + * due to its back queue). */ + sde_ier = I915_READ(SDEIER); + I915_WRITE(SDEIER, 0); + POSTING_READ(SDEIER); + gt_iir = I915_READ(GTIIR); if (gt_iir) { snb_gt_irq_handler(dev, dev_priv, gt_iir); @@ -759,6 +768,8 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg) I915_WRITE(DEIER, de_ier); POSTING_READ(DEIER); + I915_WRITE(SDEIER, sde_ier); + POSTING_READ(SDEIER); return ret; } @@ -778,7 +789,7 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) struct drm_device *dev = (struct drm_device *) arg; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = IRQ_NONE; - u32 de_iir, gt_iir, de_ier, pm_iir; + u32 de_iir, gt_iir, de_ier, pm_iir, sde_ier; atomic_inc(&dev_priv->irq_received); @@ -787,6 +798,15 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); POSTING_READ(DEIER); + /* Disable south interrupts. We'll only write to SDEIIR once, so further + * interrupts will will be stored on its back queue, and then we'll be + * able to process them after we restore SDEIER (as soon as we restore + * it, we'll get an interrupt if SDEIIR still has something to process + * due to its back queue). */ + sde_ier = I915_READ(SDEIER); + I915_WRITE(SDEIER, 0); + POSTING_READ(SDEIER); + de_iir = I915_READ(DEIIR); gt_iir = I915_READ(GTIIR); pm_iir = I915_READ(GEN6_PMIIR); @@ -849,6 +869,8 @@ static irqreturn_t ironlake_irq_handler(int irq, void *arg) done: I915_WRITE(DEIER, de_ier); POSTING_READ(DEIER); + I915_WRITE(SDEIER, sde_ier); + POSTING_READ(SDEIER); return ret; } -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 From 88c4c066c6b4db26dc4909ee94e6bf377e8e8e81 Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Mon, 4 Mar 2013 06:07:34 +0000 Subject: reset nf before xmit vxlan encapsulated packet We should reset nf settings bond to the skb as ipip/ipgre do. If not, the conntrack/nat info bond to the origin packet may continually redirect the packet to vxlan interface causing a routing loop. this is the scenario: VETP VXLAN Gateway /----\ /---------------\ | | | | | vx+--+vx --NAT-> eth0+--> Internet | | | | \----/ \---------------/ when there are any packet coming from internet to the vetp, there will be lots of garbage packets coming out the gateway's vxlan interface, but none actually sent to the physical interface, because they are redirected back to the vxlan interface in the postrouting chain of NAT rule, and dmesg complains: Mar 1 21:52:53 debian kernel: [ 8802.997699] Dead loop on virtual device vxlan0, fix it urgently! Mar 1 21:52:54 debian kernel: [ 8804.004907] Dead loop on virtual device vxlan0, fix it urgently! Mar 1 21:52:55 debian kernel: [ 8805.012189] Dead loop on virtual device vxlan0, fix it urgently! Mar 1 21:52:56 debian kernel: [ 8806.020593] Dead loop on virtual device vxlan0, fix it urgently! the patch should fix the problem Signed-off-by: Zang MingJie Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index f10e58ac9c1b..c3e3d2929ee3 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -961,6 +961,8 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev) iph->ttl = ttl ? : ip4_dst_hoplimit(&rt->dst); tunnel_ip_select_ident(skb, old_iph, &rt->dst); + nf_reset(skb); + vxlan_set_owner(dev, skb); /* See iptunnel_xmit() */ -- cgit v1.2.3 From 66d29cbc59433ba538922a9e958495156b31b83b Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Sun, 3 Mar 2013 21:48:46 +0000 Subject: benet: Wait f/w POST until timeout While PCI card faces EEH errors, reset (usually hot reset) is expected to recover from the EEH errors. After EEH core finishes the reset, the driver callback (be_eeh_reset) is called and wait the firmware to complete POST successfully. The original code would return with error once detecting failure during POST stage. That seems not enough. The patch forces the driver (be_eeh_reset) to wait the firmware completes POST until timeout, instead of returning error upon detection POST failure immediately. Also, it would improve the reliability of the EEH funtionality of the driver. Signed-off-by: Gavin Shan Acked-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be_cmds.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 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 071aea79d218..813407f66c7c 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -473,7 +473,7 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) return 0; } -static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) +static void be_POST_stage_get(struct be_adapter *adapter, u16 *stage) { u32 sem; u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH : @@ -481,11 +481,6 @@ static int be_POST_stage_get(struct be_adapter *adapter, u16 *stage) pci_read_config_dword(adapter->pdev, reg, &sem); *stage = sem & POST_STAGE_MASK; - - if ((sem >> POST_ERR_SHIFT) & POST_ERR_MASK) - return -1; - else - return 0; } int lancer_wait_ready(struct be_adapter *adapter) @@ -579,19 +574,17 @@ int be_fw_wait_ready(struct be_adapter *adapter) } do { - status = be_POST_stage_get(adapter, &stage); - if (status) { - dev_err(dev, "POST error; stage=0x%x\n", stage); - return -1; - } else if (stage != POST_STAGE_ARMFW_RDY) { - if (msleep_interruptible(2000)) { - dev_err(dev, "Waiting for POST aborted\n"); - return -EINTR; - } - timeout += 2; - } else { + be_POST_stage_get(adapter, &stage); + if (stage == POST_STAGE_ARMFW_RDY) return 0; + + dev_info(dev, "Waiting for POST, %ds elapsed\n", + timeout); + if (msleep_interruptible(2000)) { + dev_err(dev, "Waiting for POST aborted\n"); + return -EINTR; } + timeout += 2; } while (timeout < 60); dev_err(dev, "POST timeout; stage=0x%x\n", stage); -- cgit v1.2.3 From 4ecccd9edd5eb4dd185486e6e593c671484691bc Mon Sep 17 00:00:00 2001 From: "Li, Zhen-Hua" Date: Wed, 6 Mar 2013 10:43:17 +0800 Subject: iommu, x86: Add DMA remap fault reason The number of DMA fault reasons in intel's document are from 1 to 0xD, but in dmar.c fault reason 0xD is not printed out. In this document: "Intel Virtualization Technology for Directed I/O Architecture Specification" http://download.intel.com/technology/computing/vptech/Intel(r)_VT_for_Direct_IO.pdf Chapter 4. Support For Device-IOTLBs Table 6. Unsuccessful Translated Requests There is fault reason for 0xD not listed in kernel: Present context-entry used to process translation request specifies blocking of Translation Requests (Translation Type (T) field value not equal to 01b). This patch adds reason 0xD as well. Signed-off-by: Li, Zhen-Hua Cc: Joerg Roedel Cc: Donald Dutile Cc: Suresh Siddha Cc: Hannes Reinecke Link: http://lkml.kernel.org/r/1362537797-6034-1-git-send-email-zhen-hual@hp.com Signed-off-by: Ingo Molnar --- drivers/iommu/dmar.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c index dc7e478b7e5f..e5cdaf87822c 100644 --- a/drivers/iommu/dmar.c +++ b/drivers/iommu/dmar.c @@ -1083,6 +1083,7 @@ static const char *dma_remap_fault_reasons[] = "non-zero reserved fields in RTP", "non-zero reserved fields in CTP", "non-zero reserved fields in PTE", + "PCE for translation request specifies blocking", }; static const char *irq_remap_fault_reasons[] = -- cgit v1.2.3 From 60222c0c2b4d813c72296b55f07d46b19ef83e44 Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Tue, 5 Mar 2013 19:09:37 +0100 Subject: drm/i915: Fix incorrect definition of ADPA HSYNC and VSYNC bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable bits for ADPA HSYNC and VSYNC where mixed up resulting in suspend becoming standby and vice versa. Fixed by swapping their bit position. Reported-by: Ville Syrjälä Signed-off-by: Patrik Jakobsson Reviewed-by: Eric Anholt Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_reg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 527b664d3434..848992f67d56 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1613,9 +1613,9 @@ #define ADPA_CRT_HOTPLUG_FORCE_TRIGGER (1<<16) #define ADPA_USE_VGA_HVPOLARITY (1<<15) #define ADPA_SETS_HVPOLARITY 0 -#define ADPA_VSYNC_CNTL_DISABLE (1<<11) +#define ADPA_VSYNC_CNTL_DISABLE (1<<10) #define ADPA_VSYNC_CNTL_ENABLE 0 -#define ADPA_HSYNC_CNTL_DISABLE (1<<10) +#define ADPA_HSYNC_CNTL_DISABLE (1<<11) #define ADPA_HSYNC_CNTL_ENABLE 0 #define ADPA_VSYNC_ACTIVE_HIGH (1<<4) #define ADPA_VSYNC_ACTIVE_LOW 0 -- cgit v1.2.3 From 68d929862e29a8b52a7f2f2f86a0600423b093cd Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Sat, 2 Mar 2013 19:40:17 -0500 Subject: efi: be more paranoid about available space when creating variables UEFI variables are typically stored in flash. For various reasons, avaiable space is typically not reclaimed immediately upon the deletion of a variable - instead, the system will garbage collect during initialisation after a reboot. Some systems appear to handle this garbage collection extremely poorly, failing if more than 50% of the system flash is in use. This can result in the machine refusing to boot. The safest thing to do for the moment is to forbid writes if they'd end up using more than half of the storage space. We can make this more finegrained later if we come up with a method for identifying the broken machines. Signed-off-by: Matthew Garrett Cc: Josh Boyer Cc: Signed-off-by: Matt Fleming --- drivers/firmware/efivars.c | 106 +++++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 7320bf891706..0d504971ed4c 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -426,6 +426,44 @@ get_var_data(struct efivars *efivars, struct efi_variable *var) return status; } +static efi_status_t +check_var_size_locked(struct efivars *efivars, u32 attributes, + unsigned long size) +{ + u64 storage_size, remaining_size, max_size; + efi_status_t status; + const struct efivar_operations *fops = efivars->ops; + + if (!efivars->ops->query_variable_info) + return EFI_UNSUPPORTED; + + status = fops->query_variable_info(attributes, &storage_size, + &remaining_size, &max_size); + + if (status != EFI_SUCCESS) + return status; + + if (!storage_size || size > remaining_size || size > max_size || + (remaining_size - size) < (storage_size / 2)) + return EFI_OUT_OF_RESOURCES; + + return status; +} + + +static efi_status_t +check_var_size(struct efivars *efivars, u32 attributes, unsigned long size) +{ + efi_status_t status; + unsigned long flags; + + spin_lock_irqsave(&efivars->lock, flags); + status = check_var_size_locked(efivars, attributes, size); + spin_unlock_irqrestore(&efivars->lock, flags); + + return status; +} + static ssize_t efivar_guid_read(struct efivar_entry *entry, char *buf) { @@ -547,11 +585,16 @@ efivar_store_raw(struct efivar_entry *entry, const char *buf, size_t count) } spin_lock_irq(&efivars->lock); - status = efivars->ops->set_variable(new_var->VariableName, - &new_var->VendorGuid, - new_var->Attributes, - new_var->DataSize, - new_var->Data); + + status = check_var_size_locked(efivars, new_var->Attributes, + new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); + + if (status == EFI_SUCCESS || status == EFI_UNSUPPORTED) + status = efivars->ops->set_variable(new_var->VariableName, + &new_var->VendorGuid, + new_var->Attributes, + new_var->DataSize, + new_var->Data); spin_unlock_irq(&efivars->lock); @@ -702,8 +745,7 @@ static ssize_t efivarfs_file_write(struct file *file, u32 attributes; struct inode *inode = file->f_mapping->host; unsigned long datasize = count - sizeof(attributes); - unsigned long newdatasize; - u64 storage_size, remaining_size, max_size; + unsigned long newdatasize, varsize; ssize_t bytes = 0; if (count < sizeof(attributes)) @@ -722,28 +764,18 @@ static ssize_t efivarfs_file_write(struct file *file, * amounts of memory. Pick a default size of 64K if * QueryVariableInfo() isn't supported by the firmware. */ - spin_lock_irq(&efivars->lock); - if (!efivars->ops->query_variable_info) - status = EFI_UNSUPPORTED; - else { - const struct efivar_operations *fops = efivars->ops; - status = fops->query_variable_info(attributes, &storage_size, - &remaining_size, &max_size); - } - - spin_unlock_irq(&efivars->lock); + varsize = datasize + utf16_strsize(var->var.VariableName, 1024); + status = check_var_size(efivars, attributes, varsize); if (status != EFI_SUCCESS) { if (status != EFI_UNSUPPORTED) return efi_status_to_err(status); - remaining_size = 65536; + if (datasize > 65536) + return -ENOSPC; } - if (datasize > remaining_size) - return -ENOSPC; - data = kmalloc(datasize, GFP_KERNEL); if (!data) return -ENOMEM; @@ -765,6 +797,19 @@ static ssize_t efivarfs_file_write(struct file *file, */ spin_lock_irq(&efivars->lock); + /* + * Ensure that the available space hasn't shrunk below the safe level + */ + + status = check_var_size_locked(efivars, attributes, varsize); + + if (status != EFI_SUCCESS && status != EFI_UNSUPPORTED) { + spin_unlock_irq(&efivars->lock); + kfree(data); + + return efi_status_to_err(status); + } + status = efivars->ops->set_variable(var->var.VariableName, &var->var.VendorGuid, attributes, datasize, @@ -1345,7 +1390,6 @@ static int efi_pstore_write(enum pstore_type_id type, efi_guid_t vendor = LINUX_EFI_CRASH_GUID; struct efivars *efivars = psi->data; int i, ret = 0; - u64 storage_space, remaining_space, max_variable_size; efi_status_t status = EFI_NOT_FOUND; unsigned long flags; @@ -1365,11 +1409,11 @@ static int efi_pstore_write(enum pstore_type_id type, * size: a size of logging data * DUMP_NAME_LEN * 2: a maximum size of variable name */ - status = efivars->ops->query_variable_info(PSTORE_EFI_ATTRIBUTES, - &storage_space, - &remaining_space, - &max_variable_size); - if (status || remaining_space < size + DUMP_NAME_LEN * 2) { + + status = check_var_size_locked(efivars, PSTORE_EFI_ATTRIBUTES, + size + DUMP_NAME_LEN * 2); + + if (status) { spin_unlock_irqrestore(&efivars->lock, flags); *id = part; return -ENOSPC; @@ -1544,6 +1588,14 @@ static ssize_t efivar_create(struct file *filp, struct kobject *kobj, return -EINVAL; } + status = check_var_size_locked(efivars, new_var->Attributes, + new_var->DataSize + utf16_strsize(new_var->VariableName, 1024)); + + if (status && status != EFI_UNSUPPORTED) { + spin_unlock_irq(&efivars->lock); + return efi_status_to_err(status); + } + /* now *really* create the variable via EFI */ status = efivars->ops->set_variable(new_var->VariableName, &new_var->VendorGuid, -- cgit v1.2.3 From 123abd76edf56c02a76b46d3d673897177ef067b Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 5 Mar 2013 07:40:16 +0000 Subject: efivars: efivarfs_valid_name() should handle pstore syntax Stricter validation was introduced with commit da27a24383b2b ("efivarfs: guid part of filenames are case-insensitive") and commit 47f531e8ba3b ("efivarfs: Validate filenames much more aggressively"), which is necessary for the guid portion of efivarfs filenames, but we don't need to be so strict with the first part, the variable name. The UEFI specification doesn't impose any constraints on variable names other than they be a NULL-terminated string. The above commits caused a regression that resulted in users seeing the following message, $ sudo mount -v /sys/firmware/efi/efivars mount: Cannot allocate memory whenever pstore EFI variables were present in the variable store, since their variable names failed to pass the following check, /* GUID should be right after the first '-' */ if (s - 1 != strchr(str, '-')) as a typical pstore filename is of the form, dump-type0-10-1-. The fix is trivial since the guid portion of the filename is GUID_LEN bytes, we can use (len - GUID_LEN) to ensure the '-' character is where we expect it to be. (The bogus ENOMEM error value will be fixed in a separate patch.) Reported-by: Joseph Yasi Tested-by: Joseph Yasi Reported-by: Lingzhu Xiang Cc: Josh Boyer Cc: Jeremy Kerr Cc: Matthew Garrett Cc: # v3.8 Signed-off-by: Matt Fleming --- drivers/firmware/efivars.c | 4 +- tools/testing/selftests/efivarfs/efivarfs.sh | 59 ++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 0d504971ed4c..1b9a6e17e3dc 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -974,8 +974,8 @@ static bool efivarfs_valid_name(const char *str, int len) if (len < GUID_LEN + 2) return false; - /* GUID should be right after the first '-' */ - if (s - 1 != strchr(str, '-')) + /* GUID must be preceded by a '-' */ + if (*(s - 1) != '-') return false; /* diff --git a/tools/testing/selftests/efivarfs/efivarfs.sh b/tools/testing/selftests/efivarfs/efivarfs.sh index 880cdd5dc63f..77edcdcc016b 100644 --- a/tools/testing/selftests/efivarfs/efivarfs.sh +++ b/tools/testing/selftests/efivarfs/efivarfs.sh @@ -125,6 +125,63 @@ test_open_unlink() ./open-unlink $file } +# test that we can create a range of filenames +test_valid_filenames() +{ + local attrs='\x07\x00\x00\x00' + local ret=0 + + local file_list="abc dump-type0-11-1-1362436005 1234 -" + for f in $file_list; do + local file=$efivarfs_mount/$f-$test_guid + + printf "$attrs\x00" > $file + + if [ ! -e $file ]; then + echo "$file could not be created" >&2 + ret=1 + else + rm $file + fi + done + + exit $ret +} + +test_invalid_filenames() +{ + local attrs='\x07\x00\x00\x00' + local ret=0 + + local file_list=" + -1234-1234-1234-123456789abc + foo + foo-bar + -foo- + foo-barbazba-foob-foob-foob-foobarbazfoo + foo------------------------------------- + -12345678-1234-1234-1234-123456789abc + a-12345678=1234-1234-1234-123456789abc + a-12345678-1234=1234-1234-123456789abc + a-12345678-1234-1234=1234-123456789abc + a-12345678-1234-1234-1234=123456789abc + 1112345678-1234-1234-1234-123456789abc" + + for f in $file_list; do + local file=$efivarfs_mount/$f + + printf "$attrs\x00" 2>/dev/null > $file + + if [ -e $file ]; then + echo "Creating $file should have failed" >&2 + rm $file + ret=1 + fi + done + + exit $ret +} + check_prereqs rc=0 @@ -135,5 +192,7 @@ run_test test_create_read run_test test_delete run_test test_zero_size_delete run_test test_open_unlink +run_test test_valid_filenames +run_test test_invalid_filenames exit $rc -- cgit v1.2.3 From feff5dc4f98330d8152b521acc2e18c16712e6c8 Mon Sep 17 00:00:00 2001 From: Matt Fleming Date: Tue, 5 Mar 2013 12:46:30 +0000 Subject: efivarfs: return accurate error code in efivarfs_fill_super() Joseph was hitting a failure case when mounting efivarfs which resulted in an incorrect error message, $ sudo mount -v /sys/firmware/efi/efivars mount: Cannot allocate memory triggered when efivarfs_valid_name() returned -EINVAL. Make sure we pass accurate return values up the stack if efivarfs_fill_super() fails to build inodes for EFI variables. Reported-by: Joseph Yasi Reported-by: Lingzhu Xiang Cc: Josh Boyer Cc: Jeremy Kerr Cc: Matthew Garrett Cc: # v3.8 Signed-off-by: Matt Fleming --- drivers/firmware/efivars.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c index 1b9a6e17e3dc..bea32d1ef7d5 100644 --- a/drivers/firmware/efivars.c +++ b/drivers/firmware/efivars.c @@ -1163,15 +1163,22 @@ static struct dentry_operations efivarfs_d_ops = { static struct dentry *efivarfs_alloc_dentry(struct dentry *parent, char *name) { + struct dentry *d; struct qstr q; + int err; q.name = name; q.len = strlen(name); - if (efivarfs_d_hash(NULL, NULL, &q)) - return NULL; + err = efivarfs_d_hash(NULL, NULL, &q); + if (err) + return ERR_PTR(err); + + d = d_alloc(parent, &q); + if (d) + return d; - return d_alloc(parent, &q); + return ERR_PTR(-ENOMEM); } static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) @@ -1181,6 +1188,7 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) struct efivar_entry *entry, *n; struct efivars *efivars = &__efivars; char *name; + int err = -ENOMEM; efivarfs_sb = sb; @@ -1231,8 +1239,10 @@ static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) goto fail_name; dentry = efivarfs_alloc_dentry(root, name); - if (!dentry) + if (IS_ERR(dentry)) { + err = PTR_ERR(dentry); goto fail_inode; + } /* copied by the above to local storage in the dentry. */ kfree(name); @@ -1259,7 +1269,7 @@ fail_inode: fail_name: kfree(name); fail: - return -ENOMEM; + return err; } static struct dentry *efivarfs_mount(struct file_system_type *fs_type, -- cgit v1.2.3 From bdc5c1812cea6efe1aaefb3131fcba28cd0b2b68 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 5 Mar 2013 13:14:19 -0500 Subject: xen/pciback: Don't disable a PCI device that is already disabled. While shuting down a HVM guest with pci devices passed through we get this: pciback 0000:04:00.0: restoring config space at offset 0x4 (was 0x100000, writing 0x100002) ------------[ cut here ]------------ WARNING: at drivers/pci/pci.c:1397 pci_disable_device+0x88/0xa0() Hardware name: MS-7640 Device pciback disabling already-disabled device Modules linked in: Pid: 53, comm: xenwatch Not tainted 3.9.0-rc1-20130304a+ #1 Call Trace: [] warn_slowpath_common+0x7a/0xc0 [] warn_slowpath_fmt+0x41/0x50 [] pci_disable_device+0x88/0xa0 [] xen_pcibk_reset_device+0x37/0xd0 [] ? pcistub_put_pci_dev+0x6f/0x120 [] pcistub_put_pci_dev+0x8d/0x120 [] __xen_pcibk_release_devices+0x59/0xa0 This fixes the bug. CC: stable@vger.kernel.org Reported-and-Tested-by: Sander Eikelenboom Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xen-pciback/pciback_ops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c index 37c1f825f513..b98cf0c35725 100644 --- a/drivers/xen/xen-pciback/pciback_ops.c +++ b/drivers/xen/xen-pciback/pciback_ops.c @@ -113,7 +113,8 @@ void xen_pcibk_reset_device(struct pci_dev *dev) if (dev->msi_enabled) pci_disable_msi(dev); #endif - pci_disable_device(dev); + if (pci_is_enabled(dev)) + pci_disable_device(dev); pci_write_config_word(dev, PCI_COMMAND, 0); -- cgit v1.2.3 From c705c78c0d0835a4aa5d0d9a3422e3218462030c Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 5 Mar 2013 13:42:54 -0500 Subject: acpi: Export the acpi_processor_get_performance_info The git commit d5aaffa9dd531c978c6f3fea06a2972653bd7fc8 (cpufreq: handle cpufreq being disabled for all exported function) tightens the cpufreq API by returning errors when disable_cpufreq() had been called. The problem we are hitting is that the module xen-acpi-processor which uses the ACPI's functions: acpi_processor_register_performance, acpi_processor_preregister_performance, and acpi_processor_notify_smm fails at acpi_processor_register_performance with -22. Note that earlier during bootup in arch/x86/xen/setup.c there is also an call to cpufreq's API: disable_cpufreq(). This is b/c we want the Linux kernel to parse the ACPI data, but leave the cpufreq decisions to the hypervisor. In v3.9 all the checks that d5aaffa9dd531c978c6f3fea06a2972653bd7fc8 added are now hit and the calls to cpufreq_register_notifier will now fail. This means that acpi_processor_ppc_init ends up printing: "Warning: Processor Platform Limit not supported" and the acpi_processor_ppc_status is not set. The repercussions of that is that the call to acpi_processor_register_performance fails right away at: if (!(acpi_processor_ppc_status & PPC_REGISTERED)) and we don't progress any further on parsing and extracting the _P* objects. The only reason the Xen code called that function was b/c it was exported and the only way to gather the P-states. But we can also just make acpi_processor_get_performance_info be exported and not use acpi_processor_register_performance. This patch does so. Acked-by: Rafael J. Wysocki Signed-off-by: Konrad Rzeszutek Wilk --- drivers/acpi/processor_perflib.c | 4 ++-- drivers/xen/xen-acpi-processor.c | 8 ++++---- include/acpi/processor.h | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index 53e7ac9403a7..e854582f29a6 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c @@ -465,7 +465,7 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) return result; } -static int acpi_processor_get_performance_info(struct acpi_processor *pr) +int acpi_processor_get_performance_info(struct acpi_processor *pr) { int result = 0; acpi_status status = AE_OK; @@ -509,7 +509,7 @@ static int acpi_processor_get_performance_info(struct acpi_processor *pr) #endif return result; } - +EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info); int acpi_processor_notify_smm(struct module *calling_module) { acpi_status status; diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 316df65163cf..f3278a6603ca 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c @@ -500,16 +500,16 @@ static int __init xen_acpi_processor_init(void) (void)acpi_processor_preregister_performance(acpi_perf_data); for_each_possible_cpu(i) { + struct acpi_processor *pr; struct acpi_processor_performance *perf; + pr = per_cpu(processors, i); perf = per_cpu_ptr(acpi_perf_data, i); - rc = acpi_processor_register_performance(perf, i); + pr->performance = perf; + rc = acpi_processor_get_performance_info(pr); if (rc) goto err_out; } - rc = acpi_processor_notify_smm(THIS_MODULE); - if (rc) - goto err_unregister; for_each_possible_cpu(i) { struct acpi_processor *_pr; diff --git a/include/acpi/processor.h b/include/acpi/processor.h index 555d0337ad95..b327b5a9296d 100644 --- a/include/acpi/processor.h +++ b/include/acpi/processor.h @@ -235,6 +235,9 @@ extern void acpi_processor_unregister_performance(struct if a _PPC object exists, rmmod is disallowed then */ int acpi_processor_notify_smm(struct module *calling_module); +/* parsing the _P* objects. */ +extern int acpi_processor_get_performance_info(struct acpi_processor *pr); + /* for communication between multiple parts of the processor kernel module */ DECLARE_PER_CPU(struct acpi_processor *, processors); extern struct acpi_processor_errata errata; -- cgit v1.2.3 From f40ebd6bcbbd0d30591f42dc16be52b5086a366b Mon Sep 17 00:00:00 2001 From: Patrik Jakobsson Date: Tue, 5 Mar 2013 14:24:48 +0100 Subject: drm/i915: Turn off hsync and vsync on ADPA when disabling crt According to PRM we need to disable hsync and vsync even though ADPA is disabled. The previous code did infact do the opposite so we fix it. Signed-off-by: Patrik Jakobsson Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=56359 Tested-by: max Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_crt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index cfc96878d742..da1f176a40b7 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -88,7 +88,7 @@ static void intel_disable_crt(struct intel_encoder *encoder) u32 temp; temp = I915_READ(crt->adpa_reg); - temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE); + temp |= ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE; temp &= ~ADPA_DAC_ENABLE; I915_WRITE(crt->adpa_reg, temp); } -- cgit v1.2.3 From 35205b211c8d17a8a0b5e8926cb7c73e9a7ef1ad Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Mar 2013 01:03:47 +0000 Subject: sfc: Disable soft interrupt handling during efx_device_detach_sync() efx_device_detach_sync() locks all TX queues before marking the device detached and thus disabling further TX scheduling. But it can still be interrupted by TX completions which then result in TX scheduling in soft interrupt context. This will deadlock when it tries to acquire a TX queue lock that efx_device_detach_sync() already acquired. To avoid deadlock, we must use netif_tx_{,un}lock_bh(). Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/efx.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/efx.h b/drivers/net/ethernet/sfc/efx.h index 50247dfe8f57..d2f790df6dcb 100644 --- a/drivers/net/ethernet/sfc/efx.h +++ b/drivers/net/ethernet/sfc/efx.h @@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx) * TX scheduler is stopped when we're done and before * netif_device_present() becomes false. */ - netif_tx_lock(dev); + netif_tx_lock_bh(dev); netif_device_detach(dev); - netif_tx_unlock(dev); + netif_tx_unlock_bh(dev); } #endif /* EFX_EFX_H */ -- cgit v1.2.3 From c73e787a8db9117d59b5180baf83203a42ecadca Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Tue, 5 Mar 2013 17:49:39 +0000 Subject: sfc: Correct efx_rx_buffer::page_offset when EFX_PAGE_IP_ALIGN != 0 RX DMA buffers start at an offset of EFX_PAGE_IP_ALIGN bytes from the start of a cache line. This offset obviously needs to be included in the virtual address, but this was missed in commit b590ace09d51 ('sfc: Fix efx_rx_buf_offset() in the presence of swiotlb') since EFX_PAGE_IP_ALIGN is equal to 0 on both x86 and powerpc. 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 879ff5849bbd..bb579a6128c8 100644 --- a/drivers/net/ethernet/sfc/rx.c +++ b/drivers/net/ethernet/sfc/rx.c @@ -215,7 +215,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue) 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_offset = page_offset; + 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_queue->added_count; -- cgit v1.2.3 From c5b3ad4c67989c778e4753be4f91dc7193a04d21 Mon Sep 17 00:00:00 2001 From: Sathya Perla Date: Tue, 5 Mar 2013 22:23:20 +0000 Subject: be2net: use CSR-BAR SEMAPHORE reg for BE2/BE3 The SLIPORT_SEMAPHORE register shadowed in the config-space may not reflect the correct POST stage after an EEH reset in BE2/3; it may return FW_READY state even though FW is not ready. This causes the driver to prematurely poll the FW mailbox and fail. For BE2/3 use the CSR-BAR/0xac instead. Reported-by: Gavin Shan Signed-off-by: Sathya Perla Signed-off-by: David S. Miller --- drivers/net/ethernet/emulex/benet/be.h | 1 + drivers/net/ethernet/emulex/benet/be_cmds.c | 15 +++++++++------ drivers/net/ethernet/emulex/benet/be_hw.h | 4 ++-- drivers/net/ethernet/emulex/benet/be_main.c | 10 ++++++++++ 4 files changed, 22 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..29aff55f2eea 100644 --- a/drivers/net/ethernet/emulex/benet/be.h +++ b/drivers/net/ethernet/emulex/benet/be.h @@ -349,6 +349,7 @@ struct be_adapter { struct pci_dev *pdev; struct net_device *netdev; + u8 __iomem *csr; /* CSR BAR used only for BE2/3 */ u8 __iomem *db; /* Door Bell */ struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c index 813407f66c7c..3c9b4f12e3e5 100644 --- a/drivers/net/ethernet/emulex/benet/be_cmds.c +++ b/drivers/net/ethernet/emulex/benet/be_cmds.c @@ -473,14 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter) return 0; } -static void be_POST_stage_get(struct be_adapter *adapter, u16 *stage) +static u16 be_POST_stage_get(struct be_adapter *adapter) { u32 sem; - u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH : - SLIPORT_SEMAPHORE_OFFSET_BE; - pci_read_config_dword(adapter->pdev, reg, &sem); - *stage = sem & POST_STAGE_MASK; + if (BEx_chip(adapter)) + sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx); + else + pci_read_config_dword(adapter->pdev, + SLIPORT_SEMAPHORE_OFFSET_SH, &sem); + + return sem & POST_STAGE_MASK; } int lancer_wait_ready(struct be_adapter *adapter) @@ -574,7 +577,7 @@ int be_fw_wait_ready(struct be_adapter *adapter) } do { - be_POST_stage_get(adapter, &stage); + stage = be_POST_stage_get(adapter); if (stage == POST_STAGE_ARMFW_RDY) return 0; diff --git a/drivers/net/ethernet/emulex/benet/be_hw.h b/drivers/net/ethernet/emulex/benet/be_hw.h index 541d4530d5bf..62dc220695f7 100644 --- a/drivers/net/ethernet/emulex/benet/be_hw.h +++ b/drivers/net/ethernet/emulex/benet/be_hw.h @@ -32,8 +32,8 @@ #define MPU_EP_CONTROL 0 /********** MPU semphore: used for SH & BE *************/ -#define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c -#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 +#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */ +#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */ #define POST_STAGE_MASK 0x0000FFFF #define POST_ERR_MASK 0x1 #define POST_ERR_SHIFT 31 diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c index 3860888ac711..08e54f3d288b 100644 --- a/drivers/net/ethernet/emulex/benet/be_main.c +++ b/drivers/net/ethernet/emulex/benet/be_main.c @@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev) static void be_unmap_pci_bars(struct be_adapter *adapter) { + if (adapter->csr) + pci_iounmap(adapter->pdev, adapter->csr); if (adapter->db) pci_iounmap(adapter->pdev, adapter->db); } @@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter) adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >> SLI_INTF_IF_TYPE_SHIFT; + if (BEx_chip(adapter) && be_physfn(adapter)) { + adapter->csr = pci_iomap(adapter->pdev, 2, 0); + if (adapter->csr == NULL) + return -ENOMEM; + } + addr = pci_iomap(adapter->pdev, db_bar(adapter), 0); if (addr == NULL) goto pci_map_err; @@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev) pci_restore_state(pdev); /* Check if card is ok and fw is ready */ + dev_info(&adapter->pdev->dev, + "Waiting for FW to be ready after EEH reset\n"); status = be_fw_wait_ready(adapter); if (status) return PCI_ERS_RESULT_DISCONNECT; -- cgit v1.2.3 From f8af75f3517a24838a36eb5797a1a3e60bf9e276 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 6 Mar 2013 11:02:37 +0000 Subject: tun: add a missing nf_reset() in tun_net_xmit() Dave reported following crash : general protection fault: 0000 [#1] SMP CPU 2 Pid: 25407, comm: qemu-kvm Not tainted 3.7.9-205.fc18.x86_64 #1 Hewlett-Packard HP Z400 Workstation/0B4Ch RIP: 0010:[] [] destroy_conntrack+0x35/0x120 [nf_conntrack] RSP: 0018:ffff880276913d78 EFLAGS: 00010206 RAX: 50626b6b7876376c RBX: ffff88026e530d68 RCX: ffff88028d158e00 RDX: ffff88026d0d5470 RSI: 0000000000000011 RDI: 0000000000000002 RBP: ffff880276913d88 R08: 0000000000000000 R09: ffff880295002900 R10: 0000000000000000 R11: 0000000000000003 R12: ffffffff81ca3b40 R13: ffffffff8151a8e0 R14: ffff880270875000 R15: 0000000000000002 FS: 00007ff3bce38a00(0000) GS:ffff88029fc40000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 00007fd1430bd000 CR3: 000000027042b000 CR4: 00000000000027e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process qemu-kvm (pid: 25407, threadinfo ffff880276912000, task ffff88028c369720) Stack: ffff880156f59100 ffff880156f59100 ffff880276913d98 ffffffff815534f7 ffff880276913db8 ffffffff8151a74b ffff880270875000 ffff880156f59100 ffff880276913dd8 ffffffff8151a5a6 ffff880276913dd8 ffff88026d0d5470 Call Trace: [] nf_conntrack_destroy+0x17/0x20 [] skb_release_head_state+0x7b/0x100 [] __kfree_skb+0x16/0xa0 [] kfree_skb+0x36/0xa0 [] skb_queue_purge+0x20/0x40 [] __tun_detach+0x117/0x140 [tun] [] tun_chr_close+0x3c/0xd0 [tun] [] __fput+0xec/0x240 [] ____fput+0xe/0x10 [] task_work_run+0xa7/0xe0 [] do_notify_resume+0x71/0xb0 [] int_signal+0x12/0x17 Code: 00 00 04 48 89 e5 41 54 53 48 89 fb 4c 8b a7 e8 00 00 00 0f 85 de 00 00 00 0f b6 73 3e 0f b7 7b 2a e8 10 40 00 00 48 85 c0 74 0e <48> 8b 40 28 48 85 c0 74 05 48 89 df ff d0 48 c7 c7 08 6a 3a a0 RIP [] destroy_conntrack+0x35/0x120 [nf_conntrack] RSP This is because tun_net_xmit() needs to call nf_reset() before queuing skb into receive_queue Reported-by: Dave Jones Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/tun.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 2c6a22e278ea..b7c457adc0dc 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -747,6 +747,8 @@ static netdev_tx_t tun_net_xmit(struct sk_buff *skb, struct net_device *dev) goto drop; skb_orphan(skb); + nf_reset(skb); + /* Enqueue packet */ skb_queue_tail(&tfile->socket.sk->sk_receive_queue, skb); -- cgit v1.2.3 From 907cc908108b16ae87b7165be992511c968159f0 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Tue, 5 Mar 2013 14:15:27 -0800 Subject: cpufreq / intel_pstate: Fix intel_pstate_init() error path If cpufreq_register_driver() fails just free memory that has been allocated and return. intel_pstate_exit() function is removed since we are built-in only now there is no reason for a module exit procedure. Reported-by: Konrad Rzeszutek Wilk Signed-off-by: Dirk Brandewie Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 39 +++++++++++---------------------------- 1 file changed, 11 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 096fde0ebcb5..46a23b65dfc8 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -747,37 +747,11 @@ static struct cpufreq_driver intel_pstate_driver = { .owner = THIS_MODULE, }; -static void intel_pstate_exit(void) -{ - int cpu; - - sysfs_remove_group(intel_pstate_kobject, - &intel_pstate_attr_group); - debugfs_remove_recursive(debugfs_parent); - - cpufreq_unregister_driver(&intel_pstate_driver); - - if (!all_cpu_data) - return; - - get_online_cpus(); - for_each_online_cpu(cpu) { - if (all_cpu_data[cpu]) { - del_timer_sync(&all_cpu_data[cpu]->timer); - kfree(all_cpu_data[cpu]); - } - } - - put_online_cpus(); - vfree(all_cpu_data); -} -module_exit(intel_pstate_exit); - static int __initdata no_load; static int __init intel_pstate_init(void) { - int rc = 0; + int cpu, rc = 0; const struct x86_cpu_id *id; if (no_load) @@ -802,7 +776,16 @@ static int __init intel_pstate_init(void) intel_pstate_sysfs_expose_params(); return rc; out: - intel_pstate_exit(); + get_online_cpus(); + for_each_online_cpu(cpu) { + if (all_cpu_data[cpu]) { + del_timer_sync(&all_cpu_data[cpu]->timer); + kfree(all_cpu_data[cpu]); + } + } + + put_online_cpus(); + vfree(all_cpu_data); return -ENODEV; } device_initcall(intel_pstate_init); -- cgit v1.2.3 From d3929b832833db870af72479666fa4e4d043e02e Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Tue, 5 Mar 2013 14:15:26 -0800 Subject: cpufreq / intel_pstate: Do not load on VM that does not report max P state. It seems some VMs support the P state MSRs but return zeros. Fail gracefully if we are running in this environment. References: https://bugzilla.redhat.com/show_bug.cgi?id=916833 Reported-by: Josh Boyer Signed-off-by: Dirk Brandewie Acked-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/cpufreq/intel_pstate.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 46a23b65dfc8..f6dd1e761129 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -662,6 +662,9 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy) cpu = all_cpu_data[policy->cpu]; + if (!policy->cpuinfo.max_freq) + return -ENODEV; + intel_pstate_get_min_max(cpu, &min, &max); limits.min_perf_pct = (policy->min * 100) / policy->cpuinfo.max_freq; -- cgit v1.2.3 From ad4e1a7caf937ad395ced585ca85a7d14395dc80 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Sun, 17 Feb 2013 19:42:48 +0800 Subject: gpio: fix wrong checking condition for gpio range If index++ calculates from 0, the checking condition of "while (index++)" fails & it doesn't check any more. It doesn't follow the loop that used at here. Replace it by endless loop at here. Then it keeps parsing "gpio-ranges" property until it ends. Signed-off-by: Haojian Zhuang Reviewed-by: Linus Walleij Signed-off-by: Linus Walleij --- drivers/gpio/gpiolib-of.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c index a71a54a3e3f7..5150df6cba08 100644 --- a/drivers/gpio/gpiolib-of.c +++ b/drivers/gpio/gpiolib-of.c @@ -193,7 +193,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (!np) return; - do { + for (;; index++) { ret = of_parse_phandle_with_args(np, "gpio-ranges", "#gpio-range-cells", index, &pinspec); if (ret) @@ -222,8 +222,7 @@ static void of_gpiochip_add_pin_range(struct gpio_chip *chip) if (ret) break; - - } while (index++); + } } #else -- cgit v1.2.3 From daec90e7382cbd0e73eb6861109b3da91e5ab1f3 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 27 Feb 2013 15:52:56 +0100 Subject: USB: option: add Huawei E5331 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another device using CDC ACM with vendor specific protocol to mark serial functions. Cc: stable Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index f7d339d8187b..b6266bd92959 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -579,6 +579,7 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(QUANTA_VENDOR_ID, 0xea42), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t) &net_intf1_blacklist }, -- cgit v1.2.3 From fbb8c745ec20fd9e6ba9af56dabab987c765263c Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Tue, 5 Mar 2013 09:58:42 +0100 Subject: USB: storage: in-kernel modeswitching is deprecated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Acked-by: Matthew Dharm Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 72923b56bbf6..731c1d75716d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -53,6 +53,14 @@ * as opposed to devices that do something strangely or wrongly. */ +/* In-kernel mode switching is deprecated. Do not add new devices to + * this list for the sole purpose of switching them to a different + * mode. Existing userspace solutions are superior. + * + * New mode switching devices should instead be added to the database + * maintained at http://www.draisberghof.de/usb_modeswitch/ + */ + #if !defined(CONFIG_USB_STORAGE_SDDR09) && \ !defined(CONFIG_USB_STORAGE_SDDR09_MODULE) #define NO_SDDR09 -- cgit v1.2.3 From ab4b71644a26d1ab92b987b2fd30e17c25e89f85 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Mon, 4 Mar 2013 14:19:21 +0100 Subject: USB: storage: fix Huawei mode switching regression MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 200e0d99 ("USB: storage: optimize to match the Huawei USB storage devices and support new switch command" and the followup bugfix commit cd060956 ("USB: storage: properly handle the endian issues of idProduct"). The commit effectively added a large number of Huawei devices to the deprecated usb-storage mode switching logic. Many of these devices have been in use and supported by the userspace usb_modeswitch utility for years. Forcing the switching inside the kernel causes a number of regressions as a result of ignoring existing onfigurations, and also completely takes away the ability to configure mode switching per device/system/user. Known regressions caused by this: - Some of the devices support multiple modes, using different switching commands. There are existing configurations taking advantage of this. - There is a real use case for disabling mode switching and instead mounting the exposed storage device. This becomes impossible with switching logic inside the usb-storage driver. - At least on device fail as a result of the usb-storage switching command, becoming completely unswitchable. This is possibly a firmware bug, but still a regression because the device work as expected using usb_modeswitch defaults. In-kernel mode switching was deprecated years ago with the development of the more user friendly userspace alternatives. The existing list of devices in usb-storage was only kept to prevent breaking already working systems. The long term plan is to remove the list, not to add to it. Ref: http://permalink.gmane.org/gmane.linux.usb.general/28543 Cc: Cc: stable Signed-off-by: Bjørn Mork Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/initializers.c | 76 +-------- drivers/usb/storage/initializers.h | 4 +- drivers/usb/storage/unusual_devs.h | 329 ++++++++++++++++++++++++++++++++++++- 3 files changed, 331 insertions(+), 78 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 7ab9046ae0ec..105d900150c1 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c @@ -92,8 +92,8 @@ int usb_stor_ucr61s2b_init(struct us_data *us) return 0; } -/* This places the HUAWEI usb dongles in multi-port mode */ -static int usb_stor_huawei_feature_init(struct us_data *us) +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us) { int result; @@ -104,75 +104,3 @@ static int usb_stor_huawei_feature_init(struct us_data *us) US_DEBUGP("Huawei mode set result is %d\n", result); return 0; } - -/* - * It will send a scsi switch command called rewind' to huawei dongle. - * When the dongle receives this command at the first time, - * it will reboot immediately. After rebooted, it will ignore this command. - * So it is unnecessary to read its response. - */ -static int usb_stor_huawei_scsi_init(struct us_data *us) -{ - int result = 0; - int act_len = 0; - struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf; - char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN); - bcbw->Tag = 0; - bcbw->DataTransferLength = 0; - bcbw->Flags = bcbw->Lun = 0; - bcbw->Length = sizeof(rewind_cmd); - memset(bcbw->CDB, 0, sizeof(bcbw->CDB)); - memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd)); - - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw, - US_BULK_CB_WRAP_LEN, &act_len); - US_DEBUGP("transfer actual length=%d, result=%d\n", act_len, result); - return result; -} - -/* - * It tries to find the supported Huawei USB dongles. - * In Huawei, they assign the following product IDs - * for all of their mobile broadband dongles, - * including the new dongles in the future. - * So if the product ID is not included in this list, - * it means it is not Huawei's mobile broadband dongles. - */ -static int usb_stor_huawei_dongles_pid(struct us_data *us) -{ - struct usb_interface_descriptor *idesc; - int idProduct; - - idesc = &us->pusb_intf->cur_altsetting->desc; - idProduct = le16_to_cpu(us->pusb_dev->descriptor.idProduct); - /* The first port is CDROM, - * means the dongle in the single port mode, - * and a switch command is required to be sent. */ - if (idesc && idesc->bInterfaceNumber == 0) { - if ((idProduct == 0x1001) - || (idProduct == 0x1003) - || (idProduct == 0x1004) - || (idProduct >= 0x1401 && idProduct <= 0x1500) - || (idProduct >= 0x1505 && idProduct <= 0x1600) - || (idProduct >= 0x1c02 && idProduct <= 0x2202)) { - return 1; - } - } - return 0; -} - -int usb_stor_huawei_init(struct us_data *us) -{ - int result = 0; - - if (usb_stor_huawei_dongles_pid(us)) { - if (le16_to_cpu(us->pusb_dev->descriptor.idProduct) >= 0x1446) - result = usb_stor_huawei_scsi_init(us); - else - result = usb_stor_huawei_feature_init(us); - } - return result; -} diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index 5376d4fc76f0..529327fbb06b 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h @@ -46,5 +46,5 @@ int usb_stor_euscsi_init(struct us_data *us); * flash reader */ int usb_stor_ucr61s2b_init(struct us_data *us); -/* This places the HUAWEI usb dongles in multi-port mode */ -int usb_stor_huawei_init(struct us_data *us); +/* This places the HUAWEI E220 devices in multi-port mode */ +int usb_stor_huawei_e220_init(struct us_data *us); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 731c1d75716d..da04a074e790 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1535,10 +1535,335 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, /* Reported by fangxiaozhi * This brings the HUAWEI data card devices into multi-port mode */ -UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50, +UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000, "HUAWEI MOBILE", "Mass Storage", - USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init, + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1402, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1404, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1407, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x140F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x141F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1420, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1421, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1422, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1423, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1424, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1425, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1426, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1427, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1428, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1429, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x142F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1430, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1431, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1432, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1433, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1434, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1435, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1436, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1437, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1438, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x1439, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143A, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143B, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143C, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143D, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143E, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, + 0), +UNUSUAL_DEV( 0x12d1, 0x143F, 0x0000, 0x0000, + "HUAWEI MOBILE", + "Mass Storage", + USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init, 0), /* Reported by Vilius Bilinkevicius 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 518868c8fe70c98d4167ad62dac3ad3cf85c2def Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 5 Mar 2013 23:16:44 +0100 Subject: usb: gadget: fix omap_udc build errors 1bf0cf6040 "usb: gadget: omap_udc: convert to udc_start/udc_stop" made some trivial changes but was missing a ';' character. 8c4cc00552 "ARM: OMAP1: DMA: Moving OMAP1 DMA channel definitions to mach-omap1" added a definition for OMAP_DMA_USB_W2FC_TX0 to the driver while making the header file it was defined in unavailable for drivers, but this driver actually needs OMAP_DMA_USB_W2FC_RX0 as well. Both changes appear trivial, so let's add the missing semicolon and the macro definition. Acked-by: Felipe Balbi Signed-off-by: Arnd Bergmann Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/omap_udc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 06be85c2b233..f8445653577f 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c @@ -62,6 +62,7 @@ #define DRIVER_VERSION "4 October 2004" #define OMAP_DMA_USB_W2FC_TX0 29 +#define OMAP_DMA_USB_W2FC_RX0 26 /* * The OMAP UDC needs _very_ early endpoint setup: before enabling the @@ -1310,7 +1311,7 @@ static int omap_pullup(struct usb_gadget *gadget, int is_on) } static int omap_udc_start(struct usb_gadget *g, - struct usb_gadget_driver *driver) + struct usb_gadget_driver *driver); static int omap_udc_stop(struct usb_gadget *g, struct usb_gadget_driver *driver); -- cgit v1.2.3 From 1941138e1c024ecb5bd797d414928d3eb94d8662 Mon Sep 17 00:00:00 2001 From: Christian Schmiedl Date: Wed, 6 Mar 2013 17:08:50 +0100 Subject: USB: added support for Cinterion's products AH6 and PLS8 add support for Cinterion's products AH6 and PLS8 by adding Product IDs and USB_DEVICE tuples. Signed-off-by: Christian Schmiedl Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/option.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index b6266bd92959..558adfc05007 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -341,6 +341,8 @@ static void option_instat_callback(struct urb *urb); #define CINTERION_PRODUCT_EU3_E 0x0051 #define CINTERION_PRODUCT_EU3_P 0x0052 #define CINTERION_PRODUCT_PH8 0x0053 +#define CINTERION_PRODUCT_AH6 0x0055 +#define CINTERION_PRODUCT_PLS8 0x0060 /* Olivetti products */ #define OLIVETTI_VENDOR_ID 0x0b3c @@ -1261,6 +1263,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_E) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_EU3_P) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AH6) }, + { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLS8) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, { USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) }, { USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) }, -- cgit v1.2.3 From 1c2088812f095df77f4b3224b65db79d7111a300 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 6 Mar 2013 16:00:45 +0200 Subject: usb: Makefile: fix drivers/usb/phy/ Makefile entry drivers/usb/phy/ should be compiled everytime we have CONFIG_USB_OTG_UTILS enabled. phy/ should've been part of the build process based on CONFIG_USB_OTG_UTILS, don't know where I had my head when I allowed CONFIG_USB_COMMON there. In fact commit c6156328dec52a55f90688cbfad21c83f8711d84 tried to fix a previous issue but it made things even worse. The real solution is to compile phy/ based on CONFIG_USB_OTG_UTILS which gets selected by all PHY drivers. I only triggered the error recently after accepting a patch which moved a bunch of code from otg/otg.c to phy/phy.c and running 100 randconfig cycles. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index f5ed3d75fa5a..8f5ebced5df0 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile @@ -46,7 +46,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ obj-$(CONFIG_USB_SERIAL) += serial/ obj-$(CONFIG_USB) += misc/ -obj-$(CONFIG_USB_COMMON) += phy/ +obj-$(CONFIG_USB_OTG_UTILS) += phy/ obj-$(CONFIG_EARLY_PRINTK_DBGP) += early/ obj-$(CONFIG_USB_ATM) += atm/ -- cgit v1.2.3 From 5df3c35183d7963fb259eda2dbd096825861d740 Mon Sep 17 00:00:00 2001 From: Dave Tubbs Date: Wed, 27 Feb 2013 16:32:53 -0700 Subject: usb: Correction to c67x00 TD data length mask TD data length is 10 bits, correct TD_PORTLENMASK_DL. Reference Cypress Semiconductor BIOS User's Manual 1.2, page 3-10 Signed-off-by: Dave Tubbs Acked-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/usb/c67x00/c67x00-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c index a03fbc15fa9c..aa2262f89a40 100644 --- a/drivers/usb/c67x00/c67x00-sched.c +++ b/drivers/usb/c67x00/c67x00-sched.c @@ -100,7 +100,7 @@ struct c67x00_urb_priv { #define TD_PIDEP_OFFSET 0x04 #define TD_PIDEPMASK_PID 0xF0 #define TD_PIDEPMASK_EP 0x0F -#define TD_PORTLENMASK_DL 0x02FF +#define TD_PORTLENMASK_DL 0x03FF #define TD_PORTLENMASK_PN 0xC000 #define TD_STATUS_OFFSET 0x07 -- cgit v1.2.3 From b44983bb9bfa8c21fe6e85b3a32b7b458294c142 Mon Sep 17 00:00:00 2001 From: Dave Tubbs Date: Wed, 27 Feb 2013 16:32:55 -0700 Subject: usb: c67x00 RetryCnt value in c67x00 TD should be 3 RetryCnt value in c67x00 TD should be 3 (both bits set to 1). Reference Cypress Semiconductor BIOS User's Manual 1.2, page 3-14 Signed-off-by: Dave Tubbs Acked-by: Peter Korsgaard Signed-off-by: Greg Kroah-Hartman --- drivers/usb/c67x00/c67x00-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/c67x00/c67x00-sched.c b/drivers/usb/c67x00/c67x00-sched.c index aa2262f89a40..aa491627a45b 100644 --- a/drivers/usb/c67x00/c67x00-sched.c +++ b/drivers/usb/c67x00/c67x00-sched.c @@ -590,7 +590,7 @@ static int c67x00_create_td(struct c67x00_hcd *c67x00, struct urb *urb, { struct c67x00_td *td; struct c67x00_urb_priv *urbp = urb->hcpriv; - const __u8 active_flag = 1, retry_cnt = 1; + const __u8 active_flag = 1, retry_cnt = 3; __u8 cmd = 0; int tt = 0; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 From 8360cb5f389ebd36b708978e0f776a285a2deb5a Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 28 Feb 2013 12:07:27 +0100 Subject: s390/scm_blk: fix request number accounting If a block device driver cannot fetch all requests from the blocklayer it's in his responsibility to call the request function at a later time. Normally this would be done after the next irq for the underlying device is handled. However in situations where we have no outstanding request we have to schedule the request function for a later time. This is determined using an internal counter of requests issued to the hardware. In some cases where we give a request back to the block layer unhandled the number of queued requests was not adjusted. Fix this class of failures by adjusting queued_requests in all functions used to give a request back to the block layer. Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- drivers/s390/block/scm_blk.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index 9978ad4433cb..d9c7e940fa35 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -195,14 +195,18 @@ void scm_request_requeue(struct scm_request *scmrq) scm_release_cluster(scmrq); blk_requeue_request(bdev->rq, scmrq->request); + atomic_dec(&bdev->queued_reqs); scm_request_done(scmrq); scm_ensure_queue_restart(bdev); } void scm_request_finish(struct scm_request *scmrq) { + struct scm_blk_dev *bdev = scmrq->bdev; + scm_release_cluster(scmrq); blk_end_request_all(scmrq->request, scmrq->error); + atomic_dec(&bdev->queued_reqs); scm_request_done(scmrq); } @@ -231,11 +235,13 @@ static void scm_blk_request(struct request_queue *rq) return; } if (scm_need_cluster_request(scmrq)) { + atomic_inc(&bdev->queued_reqs); blk_start_request(req); scm_initiate_cluster_request(scmrq); return; } scm_request_prepare(scmrq); + atomic_inc(&bdev->queued_reqs); blk_start_request(req); ret = scm_start_aob(scmrq->aob); @@ -244,7 +250,6 @@ static void scm_blk_request(struct request_queue *rq) scm_request_requeue(scmrq); return; } - atomic_inc(&bdev->queued_reqs); } } @@ -310,7 +315,6 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev) } scm_request_finish(scmrq); - atomic_dec(&bdev->queued_reqs); spin_lock_irqsave(&bdev->lock, flags); } spin_unlock_irqrestore(&bdev->lock, flags); -- cgit v1.2.3 From 93481c90200c50c7874b6a773acc87095ee3907d Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 28 Feb 2013 12:07:38 +0100 Subject: s390/scm_drv: extend notify callback Extend the notify callback of scm_driver by an event parameter to allow to distinguish between different notifications. Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/eadm.h | 4 +++- drivers/s390/block/scm_drv.c | 16 ++++++++++------ drivers/s390/cio/scm.c | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index 8d4847191ecc..a4a1ea49003e 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -96,11 +96,13 @@ struct scm_device { #define OP_STATE_TEMP_ERR 2 #define OP_STATE_PERM_ERR 3 +enum scm_event {SCM_CHANGE}; + struct scm_driver { struct device_driver drv; int (*probe) (struct scm_device *scmdev); int (*remove) (struct scm_device *scmdev); - void (*notify) (struct scm_device *scmdev); + void (*notify) (struct scm_device *scmdev, enum scm_event event); void (*handler) (struct scm_device *scmdev, void *data, int error); }; diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index 9fa0a908607b..ff8558c4fe25 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c @@ -13,12 +13,16 @@ #include #include "scm_blk.h" -static void notify(struct scm_device *scmdev) +static void scm_notify(struct scm_device *scmdev, enum scm_event event) { - pr_info("%lu: The capabilities of the SCM increment changed\n", - (unsigned long) scmdev->address); - SCM_LOG(2, "State changed"); - SCM_LOG_STATE(2, scmdev); + switch (event) { + case SCM_CHANGE: + pr_info("%lu: The capabilities of the SCM increment changed\n", + (unsigned long) scmdev->address); + SCM_LOG(2, "State changed"); + SCM_LOG_STATE(2, scmdev); + break; + } } static int scm_probe(struct scm_device *scmdev) @@ -64,7 +68,7 @@ static struct scm_driver scm_drv = { .name = "scm_block", .owner = THIS_MODULE, }, - .notify = notify, + .notify = scm_notify, .probe = scm_probe, .remove = scm_remove, .handler = scm_blk_irq, diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index bcf20f3aa51b..31ac26499979 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -211,7 +211,7 @@ static void scmdev_update(struct scm_device *scmdev, struct sale *sale) goto out; scmdrv = to_scm_drv(scmdev->dev.driver); if (changed && scmdrv->notify) - scmdrv->notify(scmdev); + scmdrv->notify(scmdev, SCM_CHANGE); out: device_unlock(&scmdev->dev); if (changed) -- cgit v1.2.3 From 4fa3c019640ef776e393345ed35d9ec5c51aa3c1 Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 28 Feb 2013 12:07:48 +0100 Subject: s390/scm_blk: suspend writes Stop writing to scm after certain error conditions such as a concurrent firmware upgrade. Resume to normal state once scm_blk_set_available is called (due to an scm availability notification). Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/eadm.h | 2 ++ drivers/s390/block/scm_blk.c | 61 ++++++++++++++++++++++++++++++++++++++++---- drivers/s390/block/scm_blk.h | 2 ++ 3 files changed, 60 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index a4a1ea49003e..78141be88b3d 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -34,6 +34,8 @@ struct arsb { u32 reserved[4]; } __packed; +#define EQC_WR_PROHIBIT 22 + struct msb { u8 fmt:4; u8 oc:4; diff --git a/drivers/s390/block/scm_blk.c b/drivers/s390/block/scm_blk.c index d9c7e940fa35..5ac9c935c151 100644 --- a/drivers/s390/block/scm_blk.c +++ b/drivers/s390/block/scm_blk.c @@ -135,6 +135,11 @@ static const struct block_device_operations scm_blk_devops = { .release = scm_release, }; +static bool scm_permit_request(struct scm_blk_dev *bdev, struct request *req) +{ + return rq_data_dir(req) != WRITE || bdev->state != SCM_WR_PROHIBIT; +} + static void scm_request_prepare(struct scm_request *scmrq) { struct scm_blk_dev *bdev = scmrq->bdev; @@ -222,6 +227,10 @@ static void scm_blk_request(struct request_queue *rq) if (req->cmd_type != REQ_TYPE_FS) continue; + if (!scm_permit_request(bdev, req)) { + scm_ensure_queue_restart(bdev); + return; + } scmrq = scm_request_fetch(); if (!scmrq) { SCM_LOG(5, "no request"); @@ -285,6 +294,38 @@ void scm_blk_irq(struct scm_device *scmdev, void *data, int error) tasklet_hi_schedule(&bdev->tasklet); } +static void scm_blk_handle_error(struct scm_request *scmrq) +{ + struct scm_blk_dev *bdev = scmrq->bdev; + unsigned long flags; + + if (scmrq->error != -EIO) + goto restart; + + /* For -EIO the response block is valid. */ + switch (scmrq->aob->response.eqc) { + case EQC_WR_PROHIBIT: + spin_lock_irqsave(&bdev->lock, flags); + if (bdev->state != SCM_WR_PROHIBIT) + pr_info("%lu: Write access to the SCM increment is suspended\n", + (unsigned long) bdev->scmdev->address); + bdev->state = SCM_WR_PROHIBIT; + spin_unlock_irqrestore(&bdev->lock, flags); + goto requeue; + default: + break; + } + +restart: + if (!scm_start_aob(scmrq->aob)) + return; + +requeue: + spin_lock_irqsave(&bdev->rq_lock, flags); + scm_request_requeue(scmrq); + spin_unlock_irqrestore(&bdev->rq_lock, flags); +} + static void scm_blk_tasklet(struct scm_blk_dev *bdev) { struct scm_request *scmrq; @@ -298,11 +339,8 @@ static void scm_blk_tasklet(struct scm_blk_dev *bdev) spin_unlock_irqrestore(&bdev->lock, flags); if (scmrq->error && scmrq->retries-- > 0) { - if (scm_start_aob(scmrq->aob)) { - spin_lock_irqsave(&bdev->rq_lock, flags); - scm_request_requeue(scmrq); - spin_unlock_irqrestore(&bdev->rq_lock, flags); - } + scm_blk_handle_error(scmrq); + /* Request restarted or requeued, handle next. */ spin_lock_irqsave(&bdev->lock, flags); continue; @@ -336,6 +374,7 @@ int scm_blk_dev_setup(struct scm_blk_dev *bdev, struct scm_device *scmdev) } bdev->scmdev = scmdev; + bdev->state = SCM_OPER; spin_lock_init(&bdev->rq_lock); spin_lock_init(&bdev->lock); INIT_LIST_HEAD(&bdev->finished_requests); @@ -400,6 +439,18 @@ void scm_blk_dev_cleanup(struct scm_blk_dev *bdev) put_disk(bdev->gendisk); } +void scm_blk_set_available(struct scm_blk_dev *bdev) +{ + unsigned long flags; + + spin_lock_irqsave(&bdev->lock, flags); + if (bdev->state == SCM_WR_PROHIBIT) + pr_info("%lu: Write access to the SCM increment is restored\n", + (unsigned long) bdev->scmdev->address); + bdev->state = SCM_OPER; + spin_unlock_irqrestore(&bdev->lock, flags); +} + static int __init scm_blk_init(void) { int ret = -EINVAL; diff --git a/drivers/s390/block/scm_blk.h b/drivers/s390/block/scm_blk.h index 3c1ccf494647..8b387b32fd62 100644 --- a/drivers/s390/block/scm_blk.h +++ b/drivers/s390/block/scm_blk.h @@ -21,6 +21,7 @@ struct scm_blk_dev { spinlock_t rq_lock; /* guard the request queue */ spinlock_t lock; /* guard the rest of the blockdev */ atomic_t queued_reqs; + enum {SCM_OPER, SCM_WR_PROHIBIT} state; struct list_head finished_requests; #ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE struct list_head cluster_list; @@ -48,6 +49,7 @@ struct scm_request { int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *); void scm_blk_dev_cleanup(struct scm_blk_dev *); +void scm_blk_set_available(struct scm_blk_dev *); void scm_blk_irq(struct scm_device *, void *, int); void scm_request_finish(struct scm_request *); -- cgit v1.2.3 From aebfa669d9fe77876f120d3d9a28fee240fe5a8e Mon Sep 17 00:00:00 2001 From: Sebastian Ott Date: Thu, 28 Feb 2013 12:07:55 +0100 Subject: s390/scm: process availability Let the bus code process scm availability information and notify scm device drivers about the new state. Reviewed-by: Peter Oberparleiter Signed-off-by: Sebastian Ott Signed-off-by: Peter Oberparleiter Signed-off-by: Martin Schwidefsky --- arch/s390/include/asm/eadm.h | 2 +- drivers/s390/block/scm_drv.c | 7 +++++++ drivers/s390/cio/chsc.c | 17 +++++++++++++++++ drivers/s390/cio/chsc.h | 2 ++ drivers/s390/cio/scm.c | 16 ++++++++++++++++ 5 files changed, 43 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/arch/s390/include/asm/eadm.h b/arch/s390/include/asm/eadm.h index 78141be88b3d..dc9200ca32ed 100644 --- a/arch/s390/include/asm/eadm.h +++ b/arch/s390/include/asm/eadm.h @@ -98,7 +98,7 @@ struct scm_device { #define OP_STATE_TEMP_ERR 2 #define OP_STATE_PERM_ERR 3 -enum scm_event {SCM_CHANGE}; +enum scm_event {SCM_CHANGE, SCM_AVAIL}; struct scm_driver { struct device_driver drv; diff --git a/drivers/s390/block/scm_drv.c b/drivers/s390/block/scm_drv.c index ff8558c4fe25..5f6180d6ff08 100644 --- a/drivers/s390/block/scm_drv.c +++ b/drivers/s390/block/scm_drv.c @@ -15,6 +15,8 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event) { + struct scm_blk_dev *bdev = dev_get_drvdata(&scmdev->dev); + switch (event) { case SCM_CHANGE: pr_info("%lu: The capabilities of the SCM increment changed\n", @@ -22,6 +24,11 @@ static void scm_notify(struct scm_device *scmdev, enum scm_event event) SCM_LOG(2, "State changed"); SCM_LOG_STATE(2, scmdev); break; + case SCM_AVAIL: + SCM_LOG(2, "Increment available"); + SCM_LOG_STATE(2, scmdev); + scm_blk_set_available(bdev); + break; } } diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c index 31ceef1beb8b..e16c553f6556 100644 --- a/drivers/s390/cio/chsc.c +++ b/drivers/s390/cio/chsc.c @@ -433,6 +433,20 @@ static void chsc_process_sei_scm_change(struct chsc_sei_nt0_area *sei_area) " failed (rc=%d).\n", ret); } +static void chsc_process_sei_scm_avail(struct chsc_sei_nt0_area *sei_area) +{ + int ret; + + CIO_CRW_EVENT(4, "chsc: scm available information\n"); + if (sei_area->rs != 7) + return; + + ret = scm_process_availability_information(); + if (ret) + CIO_CRW_EVENT(0, "chsc: process availability information" + " failed (rc=%d).\n", ret); +} + static void chsc_process_sei_nt2(struct chsc_sei_nt2_area *sei_area) { switch (sei_area->cc) { @@ -468,6 +482,9 @@ static void chsc_process_sei_nt0(struct chsc_sei_nt0_area *sei_area) case 12: /* scm change notification */ chsc_process_sei_scm_change(sei_area); break; + case 14: /* scm available notification */ + chsc_process_sei_scm_avail(sei_area); + break; default: /* other stuff */ CIO_CRW_EVENT(2, "chsc: sei nt0 unhandled cc=%d\n", sei_area->cc); diff --git a/drivers/s390/cio/chsc.h b/drivers/s390/cio/chsc.h index 227e05f674b3..349d5fc47196 100644 --- a/drivers/s390/cio/chsc.h +++ b/drivers/s390/cio/chsc.h @@ -156,8 +156,10 @@ int chsc_scm_info(struct chsc_scm_info *scm_area, u64 token); #ifdef CONFIG_SCM_BUS int scm_update_information(void); +int scm_process_availability_information(void); #else /* CONFIG_SCM_BUS */ static inline int scm_update_information(void) { return 0; } +static inline int scm_process_availability_information(void) { return 0; } #endif /* CONFIG_SCM_BUS */ diff --git a/drivers/s390/cio/scm.c b/drivers/s390/cio/scm.c index 31ac26499979..46ec25632e8b 100644 --- a/drivers/s390/cio/scm.c +++ b/drivers/s390/cio/scm.c @@ -297,6 +297,22 @@ int scm_update_information(void) return ret; } +static int scm_dev_avail(struct device *dev, void *unused) +{ + struct scm_driver *scmdrv = to_scm_drv(dev->driver); + struct scm_device *scmdev = to_scm_dev(dev); + + if (dev->driver && scmdrv->notify) + scmdrv->notify(scmdev, SCM_AVAIL); + + return 0; +} + +int scm_process_availability_information(void) +{ + return bus_for_each_dev(&scm_bus_type, NULL, NULL, scm_dev_avail); +} + static int __init scm_init(void) { int ret; -- cgit v1.2.3 From 4e0855dff094b0d56d6b5b271e0ce7851cc1e063 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Tue, 5 Mar 2013 09:42:59 +0000 Subject: e1000e: fix pci-device enable-counter balance This patch removes redundant and unbalanced pci_disable_device() from __e1000_shutdown(). pci_clear_master() is enough, device can go into suspended state with elevated enable_cnt. Bug was introduced in commit 23606cf5d1192c2b17912cb2ef6e62f9b11de133 ("e1000e / PCI / PM: Add basic runtime PM support (rev. 4)") in v2.6.35 Cc: Bruce Allan CC: Stable Signed-off-by: Konstantin Khlebnikov Acked-by: Rafael J. Wysocki Tested-by: Borislav Petkov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index a177b8b65c44..1799021944eb 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5986,7 +5986,7 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, */ e1000e_release_hw_control(adapter); - pci_disable_device(pdev); + pci_clear_master(pdev); return 0; } -- cgit v1.2.3 From 66148babe728f3e00e13c56f6b0ecf325abd80da Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Tue, 5 Mar 2013 09:43:04 +0000 Subject: e1000e: fix runtime power management transitions This patch removes redundant actions from driver and fixes its interaction with actions in pci-bus runtime power management code. It removes pci_save_state() from __e1000_shutdown() for normal adapters, PCI bus callbacks pci_pm_*() will do all this for us. Now __e1000_shutdown() switches to D3-state only quad-port adapters, because they needs quirk for clearing false-positive error from downsteam pci-e port. pci_save_state() now called after clearing bus-master bit, thus __e1000_resume() and e1000_io_slot_reset() must set it back after restoring configuration space. This patch set get_link_status before calling pm_runtime_put() in e1000_open() to allow e1000_idle() get real link status and schedule first runtime suspend. This patch also enables wakeup for device if management mode is enabled (like for WoL) as result pci_prepare_to_sleep() would setup wakeup without special actions like custom 'enable_wakeup' sign. Cc: Bruce Allan Signed-off-by: Konstantin Khlebnikov Acked-by: Rafael J. Wysocki Tested-by: Borislav Petkov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/netdev.c | 78 +++++++----------------------- 1 file changed, 18 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 1799021944eb..2954cc7352e1 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4303,6 +4303,7 @@ static int e1000_open(struct net_device *netdev) netif_start_queue(netdev); adapter->idle_check = true; + hw->mac.get_link_status = true; pm_runtime_put(&pdev->dev); /* fire a link status change interrupt to start the watchdog */ @@ -5887,8 +5888,7 @@ release: return retval; } -static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, - bool runtime) +static int __e1000_shutdown(struct pci_dev *pdev, bool runtime) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); @@ -5912,10 +5912,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, } e1000e_reset_interrupt_capability(adapter); - retval = pci_save_state(pdev); - if (retval) - return retval; - status = er32(STATUS); if (status & E1000_STATUS_LU) wufc &= ~E1000_WUFC_LNKC; @@ -5971,13 +5967,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, ew32(WUFC, 0); } - *enable_wake = !!wufc; - - /* make sure adapter isn't asleep if manageability is enabled */ - if ((adapter->flags & FLAG_MNG_PT_ENABLED) || - (hw->mac.ops.check_mng_mode(hw))) - *enable_wake = true; - if (adapter->hw.phy.type == e1000_phy_igp_3) e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw); @@ -5988,26 +5977,6 @@ static int __e1000_shutdown(struct pci_dev *pdev, bool *enable_wake, pci_clear_master(pdev); - return 0; -} - -static void e1000_power_off(struct pci_dev *pdev, bool sleep, bool wake) -{ - if (sleep && wake) { - pci_prepare_to_sleep(pdev); - return; - } - - pci_wake_from_d3(pdev, wake); - pci_set_power_state(pdev, PCI_D3hot); -} - -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); - /* The pci-e switch on some quad port adapters will report a * correctable error when the MAC transitions from D0 to D3. To * prevent this we need to mask off the correctable errors on the @@ -6021,12 +5990,13 @@ static void e1000_complete_shutdown(struct pci_dev *pdev, bool sleep, pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, (devctl & ~PCI_EXP_DEVCTL_CERE)); - e1000_power_off(pdev, sleep, wake); + pci_save_state(pdev); + pci_prepare_to_sleep(pdev); pcie_capability_write_word(us_dev, PCI_EXP_DEVCTL, devctl); - } else { - e1000_power_off(pdev, sleep, wake); } + + return 0; } #ifdef CONFIG_PCIEASPM @@ -6084,9 +6054,7 @@ static int __e1000_resume(struct pci_dev *pdev) if (aspm_disable_flag) e1000e_disable_aspm(pdev, aspm_disable_flag); - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - pci_save_state(pdev); + pci_set_master(pdev); e1000e_set_interrupt_capability(adapter); if (netif_running(netdev)) { @@ -6152,14 +6120,8 @@ static int __e1000_resume(struct pci_dev *pdev) static int e1000_suspend(struct device *dev) { struct pci_dev *pdev = to_pci_dev(dev); - int retval; - bool wake; - - retval = __e1000_shutdown(pdev, &wake, false); - if (!retval) - e1000_complete_shutdown(pdev, true, wake); - return retval; + return __e1000_shutdown(pdev, false); } static int e1000_resume(struct device *dev) @@ -6182,13 +6144,10 @@ static int e1000_runtime_suspend(struct device *dev) struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - if (e1000e_pm_ready(adapter)) { - bool wake; - - __e1000_shutdown(pdev, &wake, true); - } + if (!e1000e_pm_ready(adapter)) + return 0; - return 0; + return __e1000_shutdown(pdev, true); } static int e1000_idle(struct device *dev) @@ -6226,12 +6185,7 @@ static int e1000_runtime_resume(struct device *dev) static void e1000_shutdown(struct pci_dev *pdev) { - bool wake = false; - - __e1000_shutdown(pdev, &wake, false); - - if (system_state == SYSTEM_POWER_OFF) - e1000_complete_shutdown(pdev, false, wake); + __e1000_shutdown(pdev, false); } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -6352,9 +6306,9 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) "Cannot re-enable PCI device after reset.\n"); result = PCI_ERS_RESULT_DISCONNECT; } else { - pci_set_master(pdev); pdev->state_saved = true; pci_restore_state(pdev); + pci_set_master(pdev); pci_enable_wake(pdev, PCI_D3hot, 0); pci_enable_wake(pdev, PCI_D3cold, 0); @@ -6783,7 +6737,11 @@ static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent) /* initialize the wol settings based on the eeprom settings */ adapter->wol = adapter->eeprom_wol; - device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol); + + /* make sure adapter isn't asleep if manageability is enabled */ + if (adapter->wol || (adapter->flags & FLAG_MNG_PT_ENABLED) || + (hw->mac.ops.check_mng_mode(hw))) + device_wakeup_enable(&pdev->dev); /* save off EEPROM version number */ e1000_read_nvm(&adapter->hw, 5, 1, &adapter->eeprom_vers); -- cgit v1.2.3 From e60b22c5b7e59db09a7c9490b1e132c7e49ae904 Mon Sep 17 00:00:00 2001 From: Konstantin Khlebnikov Date: Tue, 5 Mar 2013 09:43:09 +0000 Subject: e1000e: fix accessing to suspended device This patch fixes some annoying messages like 'Error reading PHY register' and 'Hardware Erorr' and saves several seconds on reboot. Cc: Bruce Allan Signed-off-by: Konstantin Khlebnikov Acked-by: Rafael J. Wysocki Tested-by: Borislav Petkov Tested-by: Aaron Brown Signed-off-by: Jeff Kirsher --- drivers/net/ethernet/intel/e1000e/ethtool.c | 13 +++++++++++++ drivers/net/ethernet/intel/e1000e/netdev.c | 2 ++ 2 files changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c index 2c1813737f6d..f91a8f3f9d48 100644 --- a/drivers/net/ethernet/intel/e1000e/ethtool.c +++ b/drivers/net/ethernet/intel/e1000e/ethtool.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "e1000.h" @@ -2229,7 +2230,19 @@ static int e1000e_get_ts_info(struct net_device *netdev, return 0; } +static int e1000e_ethtool_begin(struct net_device *netdev) +{ + return pm_runtime_get_sync(netdev->dev.parent); +} + +static void e1000e_ethtool_complete(struct net_device *netdev) +{ + pm_runtime_put_sync(netdev->dev.parent); +} + static const struct ethtool_ops e1000_ethtool_ops = { + .begin = e1000e_ethtool_begin, + .complete = e1000e_ethtool_complete, .get_settings = e1000_get_settings, .set_settings = e1000_set_settings, .get_drvinfo = e1000_get_drvinfo, diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 2954cc7352e1..948b86ffa4f0 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -4663,6 +4663,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) (adapter->hw.phy.media_type == e1000_media_type_copper)) { int ret_val; + pm_runtime_get_sync(&adapter->pdev->dev); ret_val = e1e_rphy(hw, MII_BMCR, &phy->bmcr); ret_val |= e1e_rphy(hw, MII_BMSR, &phy->bmsr); ret_val |= e1e_rphy(hw, MII_ADVERTISE, &phy->advertise); @@ -4673,6 +4674,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter) ret_val |= e1e_rphy(hw, MII_ESTATUS, &phy->estatus); if (ret_val) e_warn("Error reading PHY register\n"); + pm_runtime_put_sync(&adapter->pdev->dev); } else { /* Do not read PHY registers if link is not up * Set values to typical power-on defaults -- cgit v1.2.3 From dcd9006b1b053c7b1cebe81333261d4fd492ffeb Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 5 Mar 2013 17:09:00 +0100 Subject: HID: logitech-dj: do not directly call hid_output_raw_report() during probe hid_output_raw_report() makes a direct call to usb_control_msg(). However, some USB3 boards have shown that the usb device is not ready during the .probe(). This blocks the entire usb device, and the paired mice, keyboards are not functional. The dmesg output is the following: [ 11.912287] logitech-djreceiver 0003:046D:C52B.0003: hiddev0,hidraw0: USB HID v1.11 Device [Logitech USB Receiver] on usb-0000:00:14.0-2/input2 [ 11.912537] logitech-djreceiver 0003:046D:C52B.0003: logi_dj_probe:logi_dj_recv_query_paired_devices error:-32 [ 11.912636] logitech-djreceiver: probe of 0003:046D:C52B.0003 failed with error -32 Relying on the scheduled call to usbhid_submit_report() fixes the problem. related bugs: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1072082 https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1039143 https://bugzilla.redhat.com/show_bug.cgi?id=840391 https://bugzilla.kernel.org/show_bug.cgi?id=49781 Reported-and-tested-by: Bob Bowles Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-logitech-dj.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 9500f2f3f8fe..8758f38c948c 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c @@ -459,19 +459,25 @@ static int logi_dj_recv_send_report(struct dj_receiver_dev *djrcv_dev, struct dj_report *dj_report) { struct hid_device *hdev = djrcv_dev->hdev; - int sent_bytes; + struct hid_report *report; + struct hid_report_enum *output_report_enum; + u8 *data = (u8 *)(&dj_report->device_index); + int i; - if (!hdev->hid_output_raw_report) { - dev_err(&hdev->dev, "%s:" - "hid_output_raw_report is null\n", __func__); + output_report_enum = &hdev->report_enum[HID_OUTPUT_REPORT]; + report = output_report_enum->report_id_hash[REPORT_ID_DJ_SHORT]; + + if (!report) { + dev_err(&hdev->dev, "%s: unable to find dj report\n", __func__); return -ENODEV; } - sent_bytes = hdev->hid_output_raw_report(hdev, (u8 *) dj_report, - sizeof(struct dj_report), - HID_OUTPUT_REPORT); + for (i = 0; i < report->field[0]->report_count; i++) + report->field[0]->value[i] = data[i]; + + usbhid_submit_report(hdev, report, USB_DIR_OUT); - return (sent_bytes < 0) ? sent_bytes : 0; + return 0; } static int logi_dj_recv_query_paired_devices(struct dj_receiver_dev *djrcv_dev) -- cgit v1.2.3 From cc9945bf9cac03860b2f7d59882263c965c6e3af Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 26 Feb 2013 16:17:33 -0500 Subject: drm/radeon: don't set hpd, afmt interrupts when interrupts are disabled Avoids splatter if the interrupt handler is not registered due to acceleration being disabled. Signed-off-by: Alex Deucher Reviewed-by: Jerome Glisse Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index 90374dd77960..48f80cd42d8f 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -400,6 +400,9 @@ void radeon_irq_kms_enable_afmt(struct radeon_device *rdev, int block) { unsigned long irqflags; + if (!rdev->ddev->irq_enabled) + return; + spin_lock_irqsave(&rdev->irq.lock, irqflags); rdev->irq.afmt[block] = true; radeon_irq_set(rdev); @@ -419,6 +422,9 @@ void radeon_irq_kms_disable_afmt(struct radeon_device *rdev, int block) { unsigned long irqflags; + if (!rdev->ddev->irq_enabled) + return; + spin_lock_irqsave(&rdev->irq.lock, irqflags); rdev->irq.afmt[block] = false; radeon_irq_set(rdev); @@ -438,6 +444,9 @@ void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) unsigned long irqflags; int i; + if (!rdev->ddev->irq_enabled) + return; + spin_lock_irqsave(&rdev->irq.lock, irqflags); for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); @@ -458,6 +467,9 @@ void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) unsigned long irqflags; int i; + if (!rdev->ddev->irq_enabled) + return; + spin_lock_irqsave(&rdev->irq.lock, irqflags); for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); -- cgit v1.2.3 From e8fc41377f5037ff7a661ea06adc05f1daec1548 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 27 Feb 2013 12:01:58 -0500 Subject: drm/radeon: add primary dac adj quirk for R200 board vbios values are wrong leading to colors that are too bright. Use the default values instead. Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_combios.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 3e403bdda58f..78edadc9e86b 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -970,6 +970,15 @@ struct radeon_encoder_primary_dac *radeon_combios_get_primary_dac_info(struct found = 1; } + /* quirks */ + /* Radeon 9100 (R200) */ + if ((dev->pdev->device == 0x514D) && + (dev->pdev->subsystem_vendor == 0x174B) && + (dev->pdev->subsystem_device == 0x7149)) { + /* vbios value is bad, use the default */ + found = 0; + } + if (!found) /* fallback to defaults */ radeon_legacy_get_primary_dac_info_from_table(rdev, p_dac); -- cgit v1.2.3 From d808fc882928bfe3cab87dd960ca28715e461ce4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 28 Feb 2013 10:03:08 -0500 Subject: drm/radeon: skip MC reset as it's probably not hung The MC is mostly likely busy (e.g., display requests), not hung so no need to reset it. Doing an MC reset is tricky and not particularly reliable. Fixes hangs in certain cases. Reported-by: Josh Boyer Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen.c | 6 ++++++ drivers/gpu/drm/radeon/ni.c | 6 ++++++ drivers/gpu/drm/radeon/r600.c | 6 ++++++ drivers/gpu/drm/radeon/si.c | 6 ++++++ 4 files changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 3c38ea46531c..305a657bf215 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2438,6 +2438,12 @@ static u32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev) if (tmp & L2_BUSY) reset_mask |= RADEON_RESET_VMC; + /* Skip MC reset as it's mostly likely not hung, just busy */ + if (reset_mask & RADEON_RESET_MC) { + DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); + reset_mask &= ~RADEON_RESET_MC; + } + return reset_mask; } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 7cead763be9e..d4c633e12863 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1381,6 +1381,12 @@ static u32 cayman_gpu_check_soft_reset(struct radeon_device *rdev) if (tmp & L2_BUSY) reset_mask |= RADEON_RESET_VMC; + /* Skip MC reset as it's mostly likely not hung, just busy */ + if (reset_mask & RADEON_RESET_MC) { + DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); + reset_mask &= ~RADEON_RESET_MC; + } + return reset_mask; } diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 6d4b5611daf4..0740db3fcd22 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1394,6 +1394,12 @@ static u32 r600_gpu_check_soft_reset(struct radeon_device *rdev) if (r600_is_display_hung(rdev)) reset_mask |= RADEON_RESET_DISPLAY; + /* Skip MC reset as it's mostly likely not hung, just busy */ + if (reset_mask & RADEON_RESET_MC) { + DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); + reset_mask &= ~RADEON_RESET_MC; + } + return reset_mask; } diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 80979ed951eb..9128120da044 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -2284,6 +2284,12 @@ static u32 si_gpu_check_soft_reset(struct radeon_device *rdev) if (tmp & L2_BUSY) reset_mask |= RADEON_RESET_VMC; + /* Skip MC reset as it's mostly likely not hung, just busy */ + if (reset_mask & RADEON_RESET_MC) { + DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); + reset_mask &= ~RADEON_RESET_MC; + } + return reset_mask; } -- cgit v1.2.3 From 774c389fae5e5a78a4aa75f927ab59fa0ff8a0d2 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Fri, 1 Mar 2013 13:40:31 +0100 Subject: drm/radeon: don't check mipmap alignment if MIP_ADDRESS is FMASK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The MIP_ADDRESS state has 2 meanings. If the texture has one sample per pixel, it's a pointer to the mipmap chain. If the texture has multiple samples per pixel, it's a pointer to FMASK, a metadata buffer needed for reading compressed MSAA textures. The mipmap alignment rules do not apply to FMASK. Signed-off-by: Marek Olšák Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/evergreen_cs.c | 2 +- drivers/gpu/drm/radeon/radeon_drv.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 99fb13286fd0..eb8ac315f92f 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c @@ -834,7 +834,7 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, __func__, __LINE__, toffset, surf.base_align); return -EINVAL; } - if (moffset & (surf.base_align - 1)) { + if (surf.nsamples <= 1 && moffset & (surf.base_align - 1)) { dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n", __func__, __LINE__, moffset, surf.base_align); return -EINVAL; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 167758488ed6..66a7f0fd9620 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -70,9 +70,10 @@ * 2.27.0 - r600-SI: Add CS ioctl support for async DMA * 2.28.0 - r600-eg: Add MEM_WRITE packet support * 2.29.0 - R500 FP16 color clear registers + * 2.30.0 - fix for FMASK texturing */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 29 +#define KMS_DRIVER_MINOR 30 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); -- cgit v1.2.3 From 3fb817f1cd54bedd23e8913051473d574a0f1717 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 7 Mar 2013 03:46:52 +0000 Subject: net/mlx4_core: Disable mlx4_QP_ATTACH calls from guests if the host uses flow steering Guests kernels may not correctly detect if DMFS (device-enabled flow steering) is activated by the host. If DMFS is activated, the master should return error to guests which try to use the B0-steering flow calls (mlx4_QP_ATTACH). Signed-off-by: Jack Morgenstein Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 083fb48dc3d7..2995687f1aee 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2990,6 +2990,9 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, u8 steer_type_mask = 2; enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1; + if (dev->caps.steering_mode != MLX4_STEERING_MODE_B0) + return -EINVAL; + qpn = vhcr->in_modifier & 0xffffff; err = get_res(dev, slave, qpn, RES_QP, &rqp); if (err) -- cgit v1.2.3 From 0081c8f3814a8344ca975c085d987ec6c90499ae Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 7 Mar 2013 03:46:53 +0000 Subject: net/mlx4_core: Turn off device-managed FS bit in dev-cap wrapper if DMFS is not enabled Older kernels detect DMFS (device-managed flow steering) from the HCA device capability directly, regardless of whether the capability was enabled in INIT_HCA, this is fixed by commit 7b8157bed "mlx4_core: Adjustments to Flow Steering activation logic for SR-IOV" To protect against guests running kernels without this fix, the host driver should turn off the DMFS capability bit in mlx4_QUERY_DEV_CAP_wrapper. Signed-off-by: Jack Morgenstein Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/fw.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c index 50917eb3013e..f6245579962d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/fw.c +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c @@ -787,6 +787,14 @@ int mlx4_QUERY_DEV_CAP_wrapper(struct mlx4_dev *dev, int slave, bmme_flags &= ~MLX4_BMME_FLAG_TYPE_2_WIN; MLX4_PUT(outbox->buf, bmme_flags, QUERY_DEV_CAP_BMME_FLAGS_OFFSET); + /* turn off device-managed steering capability if not enabled */ + if (dev->caps.steering_mode != MLX4_STEERING_MODE_DEVICE_MANAGED) { + MLX4_GET(field, outbox->buf, + QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); + field &= 0x7f; + MLX4_PUT(outbox->buf, field, + QUERY_DEV_CAP_FLOW_STEERING_RANGE_EN_OFFSET); + } return 0; } -- cgit v1.2.3 From e7dbeba85600aa2c8daf99f8f53d9ad27e88b810 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 7 Mar 2013 03:46:54 +0000 Subject: net/mlx4_core: Fix endianness bug in set_param_l The set_param_l function assumes casting a u64 pointer to a u32 pointer allows to access the lower 32bits, but it results in writing the upper 32 bits on big endian systems. The fixed function reads the upper 32 bits of the 64 argument, and or's them with the 32 bits of the 32-bit value passed to the function. Since this is now a "read-modify-write" operation, we got many "unintialized variable" warnings which needed to be fixed as well. Reported-by: Alexander Schmidt . Signed-off-by: Jack Morgenstein Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/cq.c | 2 +- drivers/net/ethernet/mellanox/mlx4/main.c | 2 +- drivers/net/ethernet/mellanox/mlx4/mlx4.h | 2 +- drivers/net/ethernet/mellanox/mlx4/mr.c | 10 +++++----- drivers/net/ethernet/mellanox/mlx4/pd.c | 2 +- drivers/net/ethernet/mellanox/mlx4/port.c | 8 ++++---- drivers/net/ethernet/mellanox/mlx4/qp.c | 8 ++++---- drivers/net/ethernet/mellanox/mlx4/srq.c | 2 +- 8 files changed, 18 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/cq.c b/drivers/net/ethernet/mellanox/mlx4/cq.c index 7e64033d7de3..0706623cfb96 100644 --- a/drivers/net/ethernet/mellanox/mlx4/cq.c +++ b/drivers/net/ethernet/mellanox/mlx4/cq.c @@ -226,7 +226,7 @@ void __mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn) static void mlx4_cq_free_icm(struct mlx4_dev *dev, int cqn) { - u64 in_param; + u64 in_param = 0; int err; if (mlx4_is_mfunc(dev)) { diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index d180bc46826a..16abde20e1fc 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c @@ -1555,7 +1555,7 @@ void __mlx4_counter_free(struct mlx4_dev *dev, u32 idx) void mlx4_counter_free(struct mlx4_dev *dev, u32 idx) { - u64 in_param; + u64 in_param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, idx); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index cf883345af88..d738454116a0 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h @@ -1235,7 +1235,7 @@ int mlx4_get_qp_per_mgm(struct mlx4_dev *dev); static inline void set_param_l(u64 *arg, u32 val) { - *((u32 *)arg) = val; + *arg = (*arg & 0xffffffff00000000ULL) | (u64) val; } static inline void set_param_h(u64 *arg, u32 val) diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index 602ca9bf78e4..f91719a08cba 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c @@ -183,7 +183,7 @@ u32 __mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) static u32 mlx4_alloc_mtt_range(struct mlx4_dev *dev, int order) { - u64 in_param; + u64 in_param = 0; u64 out_param; int err; @@ -240,7 +240,7 @@ void __mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order) static void mlx4_free_mtt_range(struct mlx4_dev *dev, u32 offset, int order) { - u64 in_param; + u64 in_param = 0; int err; if (mlx4_is_mfunc(dev)) { @@ -351,7 +351,7 @@ void __mlx4_mpt_release(struct mlx4_dev *dev, u32 index) static void mlx4_mpt_release(struct mlx4_dev *dev, u32 index) { - u64 in_param; + u64 in_param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, index); @@ -374,7 +374,7 @@ int __mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index) static int mlx4_mpt_alloc_icm(struct mlx4_dev *dev, u32 index) { - u64 param; + u64 param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(¶m, index); @@ -395,7 +395,7 @@ void __mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index) static void mlx4_mpt_free_icm(struct mlx4_dev *dev, u32 index) { - u64 in_param; + u64 in_param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, index); diff --git a/drivers/net/ethernet/mellanox/mlx4/pd.c b/drivers/net/ethernet/mellanox/mlx4/pd.c index 1ac88637ad9d..00f223acada7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/pd.c +++ b/drivers/net/ethernet/mellanox/mlx4/pd.c @@ -101,7 +101,7 @@ void __mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) void mlx4_xrcd_free(struct mlx4_dev *dev, u32 xrcdn) { - u64 in_param; + u64 in_param = 0; int err; if (mlx4_is_mfunc(dev)) { diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index 719ead15e491..10c57c86388b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c @@ -175,7 +175,7 @@ EXPORT_SYMBOL_GPL(__mlx4_register_mac); int mlx4_register_mac(struct mlx4_dev *dev, u8 port, u64 mac) { - u64 out_param; + u64 out_param = 0; int err; if (mlx4_is_mfunc(dev)) { @@ -222,7 +222,7 @@ EXPORT_SYMBOL_GPL(__mlx4_unregister_mac); void mlx4_unregister_mac(struct mlx4_dev *dev, u8 port, u64 mac) { - u64 out_param; + u64 out_param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(&out_param, port); @@ -361,7 +361,7 @@ out: int mlx4_register_vlan(struct mlx4_dev *dev, u8 port, u16 vlan, int *index) { - u64 out_param; + u64 out_param = 0; int err; if (mlx4_is_mfunc(dev)) { @@ -406,7 +406,7 @@ out: void mlx4_unregister_vlan(struct mlx4_dev *dev, u8 port, int index) { - u64 in_param; + u64 in_param = 0; int err; if (mlx4_is_mfunc(dev)) { diff --git a/drivers/net/ethernet/mellanox/mlx4/qp.c b/drivers/net/ethernet/mellanox/mlx4/qp.c index 81e2abe07bbb..e891b058c1be 100644 --- a/drivers/net/ethernet/mellanox/mlx4/qp.c +++ b/drivers/net/ethernet/mellanox/mlx4/qp.c @@ -222,7 +222,7 @@ int __mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int mlx4_qp_reserve_range(struct mlx4_dev *dev, int cnt, int align, int *base) { - u64 in_param; + u64 in_param = 0; u64 out_param; int err; @@ -255,7 +255,7 @@ void __mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt) void mlx4_qp_release_range(struct mlx4_dev *dev, int base_qpn, int cnt) { - u64 in_param; + u64 in_param = 0; int err; if (mlx4_is_mfunc(dev)) { @@ -319,7 +319,7 @@ err_out: static int mlx4_qp_alloc_icm(struct mlx4_dev *dev, int qpn) { - u64 param; + u64 param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(¶m, qpn); @@ -344,7 +344,7 @@ void __mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn) { - u64 in_param; + u64 in_param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, qpn); diff --git a/drivers/net/ethernet/mellanox/mlx4/srq.c b/drivers/net/ethernet/mellanox/mlx4/srq.c index feda6c00829f..e329fe1f11b7 100644 --- a/drivers/net/ethernet/mellanox/mlx4/srq.c +++ b/drivers/net/ethernet/mellanox/mlx4/srq.c @@ -149,7 +149,7 @@ void __mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn) static void mlx4_srq_free_icm(struct mlx4_dev *dev, int srqn) { - u64 in_param; + u64 in_param = 0; if (mlx4_is_mfunc(dev)) { set_param_l(&in_param, srqn); -- cgit v1.2.3 From bfa8ab47415a87c6c93a9e54e16f2f8cc6de79af Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Thu, 7 Mar 2013 03:46:55 +0000 Subject: net/mlx4_en: Fix race when setting the device MAC address Remove unnecessary use of workqueue for the device MAC address setting flow, and fix a race when setting MAC address which was introduced by commit c07cb4b0a "net/mlx4_en: Manage hash of MAC addresses per port" The race happened when mlx4_en_replace_mac was being executed in parallel with a successive call to ndo_set_mac_address, e.g witn an A/B/A MAC setting configuration test, the third set fails. With this change we also properly report an error if set MAC fails. Signed-off-by: Yan Burman Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 42 +++++++++++++------------- drivers/net/ethernet/mellanox/mlx4/mlx4_en.h | 1 - 2 files changed, 21 insertions(+), 22 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..217e618fd712 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -650,28 +650,10 @@ u64 mlx4_en_mac_to_u64(u8 *addr) return mac; } -static int mlx4_en_set_mac(struct net_device *dev, void *addr) +static int mlx4_en_do_set_mac(struct mlx4_en_priv *priv) { - struct mlx4_en_priv *priv = netdev_priv(dev); - struct mlx4_en_dev *mdev = priv->mdev; - struct sockaddr *saddr = addr; - - if (!is_valid_ether_addr(saddr->sa_data)) - return -EADDRNOTAVAIL; - - memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); - queue_work(mdev->workqueue, &priv->mac_task); - return 0; -} - -static void mlx4_en_do_set_mac(struct work_struct *work) -{ - struct mlx4_en_priv *priv = container_of(work, struct mlx4_en_priv, - mac_task); - struct mlx4_en_dev *mdev = priv->mdev; int err = 0; - mutex_lock(&mdev->state_lock); if (priv->port_up) { /* Remove old MAC and insert the new one */ err = mlx4_en_replace_mac(priv, priv->base_qpn, @@ -683,7 +665,26 @@ static void mlx4_en_do_set_mac(struct work_struct *work) } else en_dbg(HW, priv, "Port is down while registering mac, exiting...\n"); + return err; +} + +static int mlx4_en_set_mac(struct net_device *dev, void *addr) +{ + struct mlx4_en_priv *priv = netdev_priv(dev); + struct mlx4_en_dev *mdev = priv->mdev; + struct sockaddr *saddr = addr; + int err; + + if (!is_valid_ether_addr(saddr->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, saddr->sa_data, ETH_ALEN); + + mutex_lock(&mdev->state_lock); + err = mlx4_en_do_set_mac(priv); mutex_unlock(&mdev->state_lock); + + return err; } static void mlx4_en_clear_list(struct net_device *dev) @@ -1348,7 +1349,7 @@ static void mlx4_en_do_get_stats(struct work_struct *work) queue_delayed_work(mdev->workqueue, &priv->stats_task, STATS_DELAY); } if (mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port]) { - queue_work(mdev->workqueue, &priv->mac_task); + mlx4_en_do_set_mac(priv); mdev->mac_removed[MLX4_MAX_PORTS + 1 - priv->port] = 0; } mutex_unlock(&mdev->state_lock); @@ -2078,7 +2079,6 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port, priv->msg_enable = MLX4_EN_MSG_LEVEL; spin_lock_init(&priv->stats_lock); INIT_WORK(&priv->rx_mode_task, mlx4_en_do_set_rx_mode); - INIT_WORK(&priv->mac_task, mlx4_en_do_set_mac); INIT_WORK(&priv->watchdog_task, mlx4_en_restart); INIT_WORK(&priv->linkstate_task, mlx4_en_linkstate); INIT_DELAYED_WORK(&priv->stats_task, mlx4_en_do_get_stats); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index c313d7e943a9..f710b7ce0dcb 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -509,7 +509,6 @@ struct mlx4_en_priv { struct mlx4_en_cq rx_cq[MAX_RX_RINGS]; struct mlx4_qp drop_qp; struct work_struct rx_mode_task; - struct work_struct mac_task; struct work_struct watchdog_task; struct work_struct linkstate_task; struct delayed_work stats_task; -- cgit v1.2.3 From 83a5a6cef40616d19a388f560447e99c2ca04d1e Mon Sep 17 00:00:00 2001 From: Yan Burman Date: Thu, 7 Mar 2013 03:46:56 +0000 Subject: net/mlx4_en: Cleanup MAC resources on module unload or port stop Make sure we cleanup all MAC related resources (entries in the port MAC table and steering rules) when stopping a port or when the driver is unloaded. The leak was introduced by commit 07cb4b0a "net/mlx4_en: Manage hash of MAC addresses per port". Signed-off-by: Yan Burman Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 36 ++++++++++++++------------ 1 file changed, 20 insertions(+), 16 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 217e618fd712..7fd0936967c4 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -565,34 +565,38 @@ static void mlx4_en_put_qp(struct mlx4_en_priv *priv) struct mlx4_en_dev *mdev = priv->mdev; struct mlx4_dev *dev = mdev->dev; int qpn = priv->base_qpn; - u64 mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); - - en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", - priv->dev->dev_addr); - mlx4_unregister_mac(dev, priv->port, mac); + u64 mac; - if (dev->caps.steering_mode != MLX4_STEERING_MODE_A0) { + if (dev->caps.steering_mode == MLX4_STEERING_MODE_A0) { + mac = mlx4_en_mac_to_u64(priv->dev->dev_addr); + en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", + priv->dev->dev_addr); + mlx4_unregister_mac(dev, priv->port, mac); + } else { struct mlx4_mac_entry *entry; struct hlist_node *tmp; struct hlist_head *bucket; - unsigned int mac_hash; + unsigned int i; - mac_hash = priv->dev->dev_addr[MLX4_EN_MAC_HASH_IDX]; - bucket = &priv->mac_hash[mac_hash]; - hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { - if (ether_addr_equal_64bits(entry->mac, - priv->dev->dev_addr)) { - en_dbg(DRV, priv, "Releasing qp: port %d, MAC %pM, qpn %d\n", - priv->port, priv->dev->dev_addr, qpn); + for (i = 0; i < MLX4_EN_MAC_HASH_SIZE; ++i) { + bucket = &priv->mac_hash[i]; + hlist_for_each_entry_safe(entry, tmp, bucket, hlist) { + mac = mlx4_en_mac_to_u64(entry->mac); + en_dbg(DRV, priv, "Registering MAC: %pM for deleting\n", + entry->mac); mlx4_en_uc_steer_release(priv, entry->mac, qpn, entry->reg_id); - mlx4_qp_release_range(dev, qpn, 1); + mlx4_unregister_mac(dev, priv->port, mac); hlist_del_rcu(&entry->hlist); kfree_rcu(entry, rcu); - break; } } + + en_dbg(DRV, priv, "Releasing qp: port %d, qpn %d\n", + priv->port, qpn); + mlx4_qp_release_range(dev, qpn, 1); + priv->flags &= ~MLX4_EN_FLAG_FORCE_PROMISC; } } -- cgit v1.2.3 From a229e488ac3f904d06c20d8d3f47831db3c7a15a Mon Sep 17 00:00:00 2001 From: Amir Vadai Date: Thu, 7 Mar 2013 03:46:57 +0000 Subject: net/mlx4_en: Disable RFS when running in SRIOV mode Commit 37706996 "mlx4_en: fix allocation of CPU affinity reverse-map" fixed a bug when mlx4_dev->caps.comp_pool is larger from the device rx rings, but introduced a regression. When the mlx4_core is activating its "legacy mode" (e.g when running in SRIOV mode) w.r.t to EQs/IRQs usage, comp_pool becomes zero and we're crashing on divide by zero alloc_cpu_rmap. Fix that by enabling RFS only when running in non-legacy mode. Reported-by: Yan Burman Cc: Kleber Sacilotto de Souza Signed-off-by: Amir Vadai Signed-off-by: Or Gerlitz Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 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 7fd0936967c4..995d4b6d5c1e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c @@ -1833,9 +1833,11 @@ int mlx4_en_alloc_resources(struct mlx4_en_priv *priv) } #ifdef CONFIG_RFS_ACCEL - priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); - if (!priv->dev->rx_cpu_rmap) - goto err; + if (priv->mdev->dev->caps.comp_pool) { + priv->dev->rx_cpu_rmap = alloc_irq_cpu_rmap(priv->mdev->dev->caps.comp_pool); + if (!priv->dev->rx_cpu_rmap) + goto err; + } #endif return 0; -- cgit v1.2.3 From e4fabf2b6e6d75752d5eede57f23ff8e9c6aa09b Mon Sep 17 00:00:00 2001 From: Bhavesh Davda Date: Wed, 6 Mar 2013 12:04:53 +0000 Subject: vmxnet3: prevent div-by-zero panic when ring resizing uninitialized dev Linux is free to call ethtool ops as soon as a netdev exists when probe finishes. However, we only allocate vmxnet3 tx/rx queues and initialize the rx_buf_per_pkt field in struct vmxnet3_adapter when the interface is opened (UP). Signed-off-by: Bhavesh Davda Signed-off-by: Shreyas N Bhatewara Signed-off-by: David S. Miller --- drivers/net/vmxnet3/vmxnet3_drv.c | 1 + drivers/net/vmxnet3/vmxnet3_ethtool.c | 6 ++++++ drivers/net/vmxnet3/vmxnet3_int.h | 4 ++-- 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 4aad350e4dae..eae7a03d4f9b 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c @@ -2958,6 +2958,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, adapter->num_rx_queues = num_rx_queues; adapter->num_tx_queues = num_tx_queues; + adapter->rx_buf_per_pkt = 1; size = sizeof(struct Vmxnet3_TxQueueDesc) * adapter->num_tx_queues; size += sizeof(struct Vmxnet3_RxQueueDesc) * adapter->num_rx_queues; diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c index a0feb17a0238..63a124340cbe 100644 --- a/drivers/net/vmxnet3/vmxnet3_ethtool.c +++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c @@ -472,6 +472,12 @@ vmxnet3_set_ringparam(struct net_device *netdev, VMXNET3_RX_RING_MAX_SIZE) return -EINVAL; + /* if adapter not yet initialized, do nothing */ + if (adapter->rx_buf_per_pkt == 0) { + netdev_err(netdev, "adapter not completely initialized, " + "ring size cannot be changed yet\n"); + return -EOPNOTSUPP; + } /* round it up to a multiple of VMXNET3_RING_SIZE_ALIGN */ new_tx_ring_size = (param->tx_pending + VMXNET3_RING_SIZE_MASK) & diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index 3198384689d9..35418146fa17 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h @@ -70,10 +70,10 @@ /* * Version numbers */ -#define VMXNET3_DRIVER_VERSION_STRING "1.1.29.0-k" +#define VMXNET3_DRIVER_VERSION_STRING "1.1.30.0-k" /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ -#define VMXNET3_DRIVER_VERSION_NUM 0x01011D00 +#define VMXNET3_DRIVER_VERSION_NUM 0x01011E00 #if defined(CONFIG_PCI_MSI) /* RSS only makes sense if MSI-X is supported. */ -- cgit v1.2.3 From 9cb6cb7ed11cd3b69c47bb414983603a6ff20b1d Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Wed, 6 Mar 2013 04:37:37 +0000 Subject: vxlan: fix oops when delete netns containing vxlan The following script will produce a kernel oops: sudo ip netns add v sudo ip netns exec v ip ad add 127.0.0.1/8 dev lo sudo ip netns exec v ip link set lo up sudo ip netns exec v ip ro add 224.0.0.0/4 dev lo sudo ip netns exec v ip li add vxlan0 type vxlan id 42 group 239.1.1.1 dev lo sudo ip netns exec v ip link set vxlan0 up sudo ip netns del v where inspect by gdb: Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 107] 0xffffffffa0289e33 in ?? () (gdb) bt #0 vxlan_leave_group (dev=0xffff88001bafa000) at drivers/net/vxlan.c:533 #1 vxlan_stop (dev=0xffff88001bafa000) at drivers/net/vxlan.c:1087 #2 0xffffffff812cc498 in __dev_close_many (head=head@entry=0xffff88001f2e7dc8) at net/core/dev.c:1299 #3 0xffffffff812cd920 in dev_close_many (head=head@entry=0xffff88001f2e7dc8) at net/core/dev.c:1335 #4 0xffffffff812cef31 in rollback_registered_many (head=head@entry=0xffff88001f2e7dc8) at net/core/dev.c:4851 #5 0xffffffff812cf040 in unregister_netdevice_many (head=head@entry=0xffff88001f2e7dc8) at net/core/dev.c:5752 #6 0xffffffff812cf1ba in default_device_exit_batch (net_list=0xffff88001f2e7e18) at net/core/dev.c:6170 #7 0xffffffff812cab27 in cleanup_net (work=) at net/core/net_namespace.c:302 #8 0xffffffff810540ef in process_one_work (worker=0xffff88001ba9ed40, work=0xffffffff8167d020) at kernel/workqueue.c:2157 #9 0xffffffff810549d0 in worker_thread (__worker=__worker@entry=0xffff88001ba9ed40) at kernel/workqueue.c:2276 #10 0xffffffff8105870c in kthread (_create=0xffff88001f2e5d68) at kernel/kthread.c:168 #11 #12 0x0000000000000000 in ?? () #13 0x0000000000000000 in ?? () (gdb) fr 0 #0 vxlan_leave_group (dev=0xffff88001bafa000) at drivers/net/vxlan.c:533 533 struct sock *sk = vn->sock->sk; (gdb) l 528 static int vxlan_leave_group(struct net_device *dev) 529 { 530 struct vxlan_dev *vxlan = netdev_priv(dev); 531 struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id); 532 int err = 0; 533 struct sock *sk = vn->sock->sk; 534 struct ip_mreqn mreq = { 535 .imr_multiaddr.s_addr = vxlan->gaddr, 536 .imr_ifindex = vxlan->link, 537 }; (gdb) p vn->sock $4 = (struct socket *) 0x0 The kernel calls `vxlan_exit_net` when deleting the netns before shutting down vxlan interfaces. Later the removal of all vxlan interfaces, where `vn->sock` is already gone causes the oops. so we should manually shutdown all interfaces before deleting `vn->sock` as the patch does. Signed-off-by: Zang MingJie Signed-off-by: David S. Miller --- drivers/net/vxlan.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index c3e3d2929ee3..7cee7a3068ec 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -1506,6 +1506,14 @@ static __net_init int vxlan_init_net(struct net *net) static __net_exit void vxlan_exit_net(struct net *net) { struct vxlan_net *vn = net_generic(net, vxlan_net_id); + struct vxlan_dev *vxlan; + unsigned h; + + rtnl_lock(); + for (h = 0; h < VNI_HASH_SIZE; ++h) + hlist_for_each_entry(vxlan, &vn->vni_list[h], hlist) + dev_close(vxlan->dev); + rtnl_unlock(); if (vn->sock) { sk_release_kernel(vn->sock->sk); -- cgit v1.2.3 From 80028ea1c0afc24d4ddeb8dd2a9992fff03616ca Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Wed, 6 Mar 2013 07:10:32 +0000 Subject: bonding: fire NETDEV_RELEASE event only on 0 slaves Currently, if we set up netconsole over bonding and release a slave, netconsole will stop logging on the whole bonding device. Change the behavior to stop the netconsole only when the last slave is released. Signed-off-by: Veaceslav Falico Acked-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 7bd068a6056a..8b4e96e01d6c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1964,7 +1964,6 @@ static int __bond_release_one(struct net_device *bond_dev, } block_netpoll_tx(); - call_netdevice_notifiers(NETDEV_RELEASE, bond_dev); write_lock_bh(&bond->lock); slave = bond_get_slave_by_dev(bond, slave_dev); @@ -2066,8 +2065,10 @@ static int __bond_release_one(struct net_device *bond_dev, write_unlock_bh(&bond->lock); unblock_netpoll_tx(); - if (bond->slave_cnt == 0) + if (bond->slave_cnt == 0) { call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev); + call_netdevice_notifiers(NETDEV_RELEASE, bond->dev); + } bond_compute_features(bond); if (!(bond_dev->features & NETIF_F_VLAN_CHALLENGED) && -- cgit v1.2.3 From 260055bb1f1f8b5328601816c50fd7e0dfda7dff Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 6 Mar 2013 07:49:02 +0000 Subject: mv643xx_eth: fix for disabled autoneg When autoneg has been disabled in the PHY (Marvell 88E1118 here), auto negotiation between MAC and PHY seem non-functional anymore. The only way I found to workaround this is to manually configure the MAC with the settings sent to the PHY earlier. Signed-off-by: Phil Sutter Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mv643xx_eth.c | 55 +++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mv643xx_eth.c b/drivers/net/ethernet/marvell/mv643xx_eth.c index 29140502b71a..6562c736a1d8 100644 --- a/drivers/net/ethernet/marvell/mv643xx_eth.c +++ b/drivers/net/ethernet/marvell/mv643xx_eth.c @@ -1081,6 +1081,45 @@ static void txq_set_fixed_prio_mode(struct tx_queue *txq) /* mii management interface *************************************************/ +static void mv643xx_adjust_pscr(struct mv643xx_eth_private *mp) +{ + u32 pscr = rdlp(mp, PORT_SERIAL_CONTROL); + u32 autoneg_disable = FORCE_LINK_PASS | + DISABLE_AUTO_NEG_SPEED_GMII | + DISABLE_AUTO_NEG_FOR_FLOW_CTRL | + DISABLE_AUTO_NEG_FOR_DUPLEX; + + if (mp->phy->autoneg == AUTONEG_ENABLE) { + /* enable auto negotiation */ + pscr &= ~autoneg_disable; + goto out_write; + } + + pscr |= autoneg_disable; + + if (mp->phy->speed == SPEED_1000) { + /* force gigabit, half duplex not supported */ + pscr |= SET_GMII_SPEED_TO_1000; + pscr |= SET_FULL_DUPLEX_MODE; + goto out_write; + } + + pscr &= ~SET_GMII_SPEED_TO_1000; + + if (mp->phy->speed == SPEED_100) + pscr |= SET_MII_SPEED_TO_100; + else + pscr &= ~SET_MII_SPEED_TO_100; + + if (mp->phy->duplex == DUPLEX_FULL) + pscr |= SET_FULL_DUPLEX_MODE; + else + pscr &= ~SET_FULL_DUPLEX_MODE; + +out_write: + wrlp(mp, PORT_SERIAL_CONTROL, pscr); +} + static irqreturn_t mv643xx_eth_err_irq(int irq, void *dev_id) { struct mv643xx_eth_shared_private *msp = dev_id; @@ -1499,6 +1538,7 @@ static int mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) { struct mv643xx_eth_private *mp = netdev_priv(dev); + int ret; if (mp->phy == NULL) return -EINVAL; @@ -1508,7 +1548,10 @@ mv643xx_eth_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) */ cmd->advertising &= ~ADVERTISED_1000baseT_Half; - return phy_ethtool_sset(mp->phy, cmd); + ret = phy_ethtool_sset(mp->phy, cmd); + if (!ret) + mv643xx_adjust_pscr(mp); + return ret; } static void mv643xx_eth_get_drvinfo(struct net_device *dev, @@ -2442,11 +2485,15 @@ static int mv643xx_eth_stop(struct net_device *dev) static int mv643xx_eth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct mv643xx_eth_private *mp = netdev_priv(dev); + int ret; - if (mp->phy != NULL) - return phy_mii_ioctl(mp->phy, ifr, cmd); + if (mp->phy == NULL) + return -ENOTSUPP; - return -EOPNOTSUPP; + ret = phy_mii_ioctl(mp->phy, ifr, cmd); + if (!ret) + mv643xx_adjust_pscr(mp); + return ret; } static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) -- cgit v1.2.3 From ba81276b1a5e3cf0674cb0e6d9525e5ae0c98695 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 7 Mar 2013 07:59:25 +0000 Subject: team: unsyc the devices addresses when port is removed When a team port is removed, unsync all devices addresses that may have been synched to the port devices. CC: Jiri Pirko Signed-off-by: Vlad Yasevich Acked-by: Jiri Pirko Signed-off-by: David S. Miller --- drivers/net/team/team.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 05c5efe84591..bf3419297875 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c @@ -1138,6 +1138,8 @@ static int team_port_del(struct team *team, struct net_device *port_dev) netdev_upper_dev_unlink(port_dev, dev); team_port_disable_netpoll(port); vlan_vids_del_by_dev(port_dev, dev); + dev_uc_unsync(port_dev, dev); + dev_mc_unsync(port_dev, dev); dev_close(port_dev); team_port_leave(team, port); -- cgit v1.2.3 From 87ab7f6f2874f1115817e394a7ed2dea1c72549e Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 7 Mar 2013 10:21:48 +0000 Subject: macvlan: Set IFF_UNICAST_FLT flag to prevent unnecessary promisc mode. Macvlan already supports hw address filters. Set the IFF_UNICAST_FLT so that it doesn't needlesly enter PROMISC mode when macvlans are stacked. Signed-of-by: Vlad Yasevich Signed-off-by: David S. Miller --- drivers/net/macvlan.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 417b2af1aa80..73abbc1655d5 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -660,6 +660,7 @@ void macvlan_common_setup(struct net_device *dev) ether_setup(dev); dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); + dev->priv_flags |= IFF_UNICAST_FLT; dev->netdev_ops = &macvlan_netdev_ops; dev->destructor = free_netdev; dev->header_ops = &macvlan_hard_header_ops, -- cgit v1.2.3 From cc59487a05b1aae6987b4a5d56603ed3e603f82e Mon Sep 17 00:00:00 2001 From: Christopher Harvey Date: Tue, 26 Feb 2013 10:54:22 -0500 Subject: drm/mgag200: 'fbdev_list' in 'struct mga_fbdev' is not used Signed-off-by: Christopher Harvey Signed-off-by: Dave Airlie --- drivers/gpu/drm/mgag200/mgag200_drv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h b/drivers/gpu/drm/mgag200/mgag200_drv.h index 5ea5033eae0a..4d932c46725d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_drv.h +++ b/drivers/gpu/drm/mgag200/mgag200_drv.h @@ -112,7 +112,6 @@ struct mga_framebuffer { struct mga_fbdev { struct drm_fb_helper helper; struct mga_framebuffer mfb; - struct list_head fbdev_list; void *sysram; int size; struct ttm_bo_kmap_obj mapping; -- cgit v1.2.3 From 0ba53171583f86bbcbba951fe172982f7fc3761c Mon Sep 17 00:00:00 2001 From: Christopher Harvey Date: Tue, 26 Feb 2013 10:55:44 -0500 Subject: drm/mgag200: Reject modes that are too big for VRAM A monitor or a user could request a resolution greater than the available VRAM for the backing framebuffer. This change checks the required framebuffer size against the max VRAM size and rejects modes if they are too big. This change can also remove a mode request passed in via the video= parameter. Signed-off-by: Christopher Harvey Signed-off-by: Dave Airlie --- drivers/gpu/drm/mgag200/mgag200_mode.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index d3d99a28ddef..a274b9906ef8 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -1406,6 +1406,14 @@ static int mga_vga_get_modes(struct drm_connector *connector) static int mga_vga_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode) { + struct drm_device *dev = connector->dev; + struct mga_device *mdev = (struct mga_device*)dev->dev_private; + struct mga_fbdev *mfbdev = mdev->mfbdev; + struct drm_fb_helper *fb_helper = &mfbdev->helper; + struct drm_fb_helper_connector *fb_helper_conn = NULL; + int bpp = 32; + int i = 0; + /* FIXME: Add bandwidth and g200se limitations */ if (mode->crtc_hdisplay > 2048 || mode->crtc_hsync_start > 4096 || @@ -1415,6 +1423,25 @@ static int mga_vga_mode_valid(struct drm_connector *connector, return MODE_BAD; } + /* Validate the mode input by the user */ + for (i = 0; i < fb_helper->connector_count; i++) { + if (fb_helper->connector_info[i]->connector == connector) { + /* Found the helper for this connector */ + fb_helper_conn = fb_helper->connector_info[i]; + if (fb_helper_conn->cmdline_mode.specified) { + if (fb_helper_conn->cmdline_mode.bpp_specified) { + bpp = fb_helper_conn->cmdline_mode.bpp; + } + } + } + } + + if ((mode->hdisplay * mode->vdisplay * (bpp/8)) > mdev->mc.vram_size) { + if (fb_helper_conn) + fb_helper_conn->cmdline_mode.specified = false; + return MODE_BAD; + } + return MODE_OK; } -- cgit v1.2.3 From ce495960ff33f96362cf81f0eb7c52d1a89f64be Mon Sep 17 00:00:00 2001 From: Julia Lemire Date: Thu, 7 Mar 2013 10:41:03 -0500 Subject: drm/mgag200: Bug fix: Renesas board now selects native resolution. Renesas boards were consistently defaulting to the 1024x768 resolution, regardless of the native resolution of the monitor plugged in. It was determined that the EDID of the monitor was not being read. Since the DAC is a shared line, in order to read from or write to it we must take control of the DAC clock. This can be done by setting the proper register to one. This bug fix sets the register MGA1064_GEN_IO_CTL2 to one. The DAC control line can be used to determine whether or not a new monitor has been plugged in. But since the hotplug feature is not one we will support, it has been decided to simply leave the register set to one. Signed-off-by: Julia Lemire Signed-off-by: Dave Airlie --- drivers/gpu/drm/mgag200/mgag200_i2c.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c b/drivers/gpu/drm/mgag200/mgag200_i2c.c index 5a88ec51b513..d3dcf54e6233 100644 --- a/drivers/gpu/drm/mgag200/mgag200_i2c.c +++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c @@ -92,6 +92,7 @@ struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev) int ret; int data, clock; + WREG_DAC(MGA1064_GEN_IO_CTL2, 1); WREG_DAC(MGA1064_GEN_IO_DATA, 0xff); WREG_DAC(MGA1064_GEN_IO_CTL, 0); -- cgit v1.2.3 From 36c1813bb453dd078e49bc5b3c1bf7d13535d9ff Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 5 Mar 2013 22:07:36 +0100 Subject: drm/tegra: drop "select DRM_HDMI" Commit ac24c2204a76e5b42aa103bf963ae0eda1b827f3 ("drm/tegra: Use generic HDMI infoframe helpers") added "select DRM_HDMI" to the DRM_TEGRA Kconfig entry. But there is no Kconfig symbol named DRM_HDMI. The select statement for that symbol is a nop. Drop it. What was needed to use HDMI functionality was to select HDMI (which this entry already did through depending on DRM) and to include linux/hdmi.h (which this commit also did). Signed-off-by: Paul Bolle Acked-by: Thierry Reding Signed-off-by: Dave Airlie --- drivers/gpu/drm/tegra/Kconfig | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig index c92955df0658..be1daf7344d3 100644 --- a/drivers/gpu/drm/tegra/Kconfig +++ b/drivers/gpu/drm/tegra/Kconfig @@ -4,7 +4,6 @@ config DRM_TEGRA select DRM_KMS_HELPER select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER - select DRM_HDMI select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT -- cgit v1.2.3 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 v1.2.3 From e84e7a56a3aa2963db506299e29a5f3f09377f9b Mon Sep 17 00:00:00 2001 From: Amit Shah Date: Fri, 8 Mar 2013 11:30:18 +1100 Subject: virtio: rng: disallow multiple device registrations, fixes crashes The code currently only supports one virtio-rng device at a time. Invoking guests with multiple devices causes the guest to blow up. Check if we've already registered and initialised the driver. Also cleanup in case of registration errors or hot-unplug so that a new device can be used. Reported-by: Peter Krempa Reported-by: Signed-off-by: Amit Shah Signed-off-by: Rusty Russell Cc: stable@kernel.org --- drivers/char/hw_random/virtio-rng.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 10fd71ccf587..6bf4d47324eb 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -92,14 +92,22 @@ static int probe_common(struct virtio_device *vdev) { int err; + if (vq) { + /* We only support one device for now */ + return -EBUSY; + } /* We expect a single virtqueue. */ vq = virtio_find_single_vq(vdev, random_recv_done, "input"); - if (IS_ERR(vq)) - return PTR_ERR(vq); + if (IS_ERR(vq)) { + err = PTR_ERR(vq); + vq = NULL; + return err; + } err = hwrng_register(&virtio_hwrng); if (err) { vdev->config->del_vqs(vdev); + vq = NULL; return err; } @@ -112,6 +120,7 @@ static void remove_common(struct virtio_device *vdev) busy = false; hwrng_unregister(&virtio_hwrng); vdev->config->del_vqs(vdev); + vq = NULL; } static int virtrng_probe(struct virtio_device *vdev) -- cgit v1.2.3 From 5f3347e6e75768985a088d959c49fb66263087b6 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Thu, 7 Mar 2013 13:27:33 +0000 Subject: bnx2x: Fix intermittent long KR2 link up time When a KR2 device is connected to a KR link-partner, sometimes it requires disabling KR2 for the link to come up. To get a KR2 link up later, in case no base pages are seen, the KR2 is restored. The problem was that some link partners cleared their advertised BP/NP after around two seconds, causing the driver to disable/enable KR2 link all the time. The fix was to wait at least 5 seconds before checking KR2 recovery. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 11 +++++++++++ drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 3 ++- 2 files changed, 13 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 31c5787970db..00ac4932f4c4 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -12527,6 +12527,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; vars->mac_type = MAC_TYPE_NONE; vars->phy_flags = 0; + vars->check_kr2_recovery_cnt = 0; /* Driver opens NIG-BRB filters */ bnx2x_set_rx_filter(params, 1); /* Check if link flap can be avoided */ @@ -13411,6 +13412,7 @@ static void bnx2x_disable_kr2(struct link_params *params, vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE; bnx2x_update_link_attr(params, vars->link_attr_sync); + vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT; /* Restart AN on leading lane */ bnx2x_warpcore_restart_AN_KR(phy, params); } @@ -13439,6 +13441,15 @@ static void bnx2x_check_kr2_wa(struct link_params *params, return; } + /* Once KR2 was disabled, wait 5 seconds before checking KR2 recovery + * since some switches tend to reinit the AN process and clear the + * advertised BP/NP after ~2 seconds causing the KR2 to be disabled + * and recovered many times + */ + if (vars->check_kr2_recovery_cnt > 0) { + vars->check_kr2_recovery_cnt--; + return; + } lane = bnx2x_get_warpcore_lane(phy, params); CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK, MDIO_AER_BLOCK_AER_REG, lane); diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index be5c195d03dd..f92fcf71be04 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -342,7 +342,8 @@ struct link_vars { u32 link_status; u32 eee_status; u8 fault_detected; - u8 rsrv1; + u8 check_kr2_recovery_cnt; +#define CHECK_KR2_RECOVERY_CNT 5 u16 periodic_flags; #define PERIODIC_FLAGS_LINK_EVENT 0x0001 -- cgit v1.2.3 From d9169323308a63fdd967920b9c63a00394ae7c85 Mon Sep 17 00:00:00 2001 From: Yaniv Rosner Date: Thu, 7 Mar 2013 13:27:34 +0000 Subject: bnx2x: Fix SFP+ misconfiguration in iSCSI boot scenario Fix a problem in which iSCSI-boot installation fails when switching SFP+ boot port and moving the SFP+ module prior to boot. The SFP+ insertion triggers an interrupt which configures the SFP+ module wrongly before interface is loaded. Signed-off-by: Yaniv Rosner Signed-off-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c | 6 +++++- drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h | 1 + 2 files changed, 6 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 00ac4932f4c4..77ebae0ac64a 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -8647,7 +8647,9 @@ void bnx2x_handle_module_detect_int(struct link_params *params) MDIO_WC_DEVAD, MDIO_WC_REG_DIGITAL5_MISC6, &rx_tx_in_reset); - if (!rx_tx_in_reset) { + if ((!rx_tx_in_reset) && + (params->link_flags & + PHY_INITIALIZED)) { bnx2x_warpcore_reset_lane(bp, phy, 1); bnx2x_warpcore_config_sfi(phy, params); bnx2x_warpcore_reset_lane(bp, phy, 0); @@ -12528,6 +12530,7 @@ int bnx2x_phy_init(struct link_params *params, struct link_vars *vars) vars->mac_type = MAC_TYPE_NONE; vars->phy_flags = 0; vars->check_kr2_recovery_cnt = 0; + params->link_flags = PHY_INITIALIZED; /* Driver opens NIG-BRB filters */ bnx2x_set_rx_filter(params, 1); /* Check if link flap can be avoided */ @@ -12692,6 +12695,7 @@ int bnx2x_lfa_reset(struct link_params *params, struct bnx2x *bp = params->bp; vars->link_up = 0; vars->phy_flags = 0; + params->link_flags &= ~PHY_INITIALIZED; if (!params->lfa_base) return bnx2x_link_reset(params, vars, 1); /* diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h index f92fcf71be04..56c2aae4e2c8 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h @@ -309,6 +309,7 @@ struct link_params { req_flow_ctrl is set to AUTO */ u16 link_flags; #define LINK_FLAGS_INT_DISABLED (1<<0) +#define PHY_INITIALIZED (1<<1) u32 lfa_base; }; -- cgit v1.2.3 From f39479363e0361c8bb4397481c01a7c3a1a3c8ac Mon Sep 17 00:00:00 2001 From: Chen Gang Date: Thu, 7 Mar 2013 18:25:41 +0000 Subject: drivers/isdn: checkng length to be sure not memory overflow sizeof (cmd.parm.cmsg.para) is 50 (MAX_CAPI_PARA_LEN). sizeof (cmd.parm) is 80+, but less than 100. strlen(msg) may be more than 80+ (Modem-Commandbuffer, less than 255). isdn_tty_send_msg is called by isdn_tty_parse_at the relative parameter is m->mdmcmd (atemu *m) the relative command may be "+M..." so need check the length to be sure not memory overflow. cmd.parm is a union, and need keep original valid buffer length no touch Signed-off-by: Chen Gang Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_tty.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index d8a7d8323414..ebaebdf30f98 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c @@ -902,7 +902,9 @@ isdn_tty_send_msg(modem_info *info, atemu *m, char *msg) int j; int l; - l = strlen(msg); + l = min(strlen(msg), sizeof(cmd.parm) - sizeof(cmd.parm.cmsg) + + sizeof(cmd.parm.cmsg.para) - 2); + if (!l) { isdn_tty_modem_result(RESULT_ERROR, info); return; -- cgit v1.2.3 From c390b0363d6cc201db93de69b5e88f482322d821 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 8 Mar 2013 09:42:50 +0200 Subject: usb: dwc3: ep0: fix sparc64 build drivers/usb/dwc3/ep0.c: In function `__dwc3_ep0_do_control_data': drivers/usb/dwc3/ep0.c:905: error: `typeof' applied to a bit-field Looks like a gcc-3.4.5/sparc64 bug. Cc: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Felipe Balbi --- drivers/usb/dwc3/ep0.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c index d7da073a23fe..1d139ca05ef1 100644 --- a/drivers/usb/dwc3/ep0.c +++ b/drivers/usb/dwc3/ep0.c @@ -891,7 +891,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, DWC3_TRBCTL_CONTROL_DATA); } else if (!IS_ALIGNED(req->request.length, dep->endpoint.maxpacket) && (dep->number == 0)) { - u32 transfer_size; + u32 transfer_size; + u32 maxpacket; ret = usb_gadget_map_request(&dwc->gadget, &req->request, dep->number); @@ -902,8 +903,8 @@ static void __dwc3_ep0_do_control_data(struct dwc3 *dwc, WARN_ON(req->request.length > DWC3_EP0_BOUNCE_SIZE); - transfer_size = roundup(req->request.length, - (u32) dep->endpoint.maxpacket); + maxpacket = dep->endpoint.maxpacket; + transfer_size = roundup(req->request.length, maxpacket); dwc->ep0_bounced = true; -- cgit v1.2.3 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 v1.2.3 From 5ca1088f10d6179a610067ebedc56edc7d98b986 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Thu, 7 Mar 2013 09:02:38 +0100 Subject: Revert "mtd: bcm47xxpart: improve probing of nvram partition" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit be3781b71ac03723b552dc156931620634ef1b22. Some CFE bootloaders have NVRAM at offset 0x1000. With that patch we were detecting such a bootloaders as a standard NVRAM partition. Changing anything in this pseudo-NVRAM resulted in corrupted bootloader and bricked device! Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: David Woodhouse --- drivers/mtd/bcm47xxpart.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 63feb75cc8e0..4552afbad4d0 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -19,6 +19,12 @@ /* 10 parts were found on sflash on Netgear WNDR4500 */ #define BCM47XXPART_MAX_PARTS 12 +/* + * Amount of bytes we read when analyzing each block of flash memory. + * Set it big enough to allow detecting partition and reading important data. + */ +#define BCM47XXPART_BYTES_TO_READ 0x404 + /* Magics */ #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */ #define POT_MAGIC1 0x54544f50 /* POTT */ @@ -57,17 +63,14 @@ static int bcm47xxpart_parse(struct mtd_info *master, struct trx_header *trx; int trx_part = -1; int last_trx_part = -1; - int max_bytes_to_read = 0x8004; if (blocksize <= 0x10000) blocksize = 0x10000; - if (blocksize == 0x20000) - max_bytes_to_read = 0x18004; /* Alloc */ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, GFP_KERNEL); - buf = kzalloc(max_bytes_to_read, GFP_KERNEL); + buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL); /* Parse block by block looking for magics */ for (offset = 0; offset <= master->size - blocksize; @@ -82,7 +85,7 @@ static int bcm47xxpart_parse(struct mtd_info *master, } /* Read beginning of the block */ - if (mtd_read(master, offset, max_bytes_to_read, + if (mtd_read(master, offset, BCM47XXPART_BYTES_TO_READ, &bytes_read, (uint8_t *)buf) < 0) { pr_err("mtd_read error while parsing (offset: 0x%X)!\n", offset); @@ -97,16 +100,9 @@ static int bcm47xxpart_parse(struct mtd_info *master, } /* Standard NVRAM */ - if (buf[0x000 / 4] == NVRAM_HEADER || - buf[0x1000 / 4] == NVRAM_HEADER || - buf[0x8000 / 4] == NVRAM_HEADER || - (blocksize == 0x20000 && ( - buf[0x10000 / 4] == NVRAM_HEADER || - buf[0x11000 / 4] == NVRAM_HEADER || - buf[0x18000 / 4] == NVRAM_HEADER))) { + if (buf[0x000 / 4] == NVRAM_HEADER) { bcm47xxpart_add_part(&parts[curr_part++], "nvram", offset, 0); - offset = rounddown(offset, blocksize); continue; } -- cgit v1.2.3 From 91d542f4dcc231749c36114ed8e26bb27d4521e4 Mon Sep 17 00:00:00 2001 From: RafaÅ‚ MiÅ‚ecki Date: Thu, 7 Mar 2013 09:02:39 +0100 Subject: mtd: bcm47xxpart: look for NVRAM at the end of device MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NVRAM is always placed at the end of device and it does not have to start at the beginning of a block, so check few possible offsets. Signed-off-by: RafaÅ‚ MiÅ‚ecki Signed-off-by: David Woodhouse --- drivers/mtd/bcm47xxpart.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 4552afbad4d0..9279a9174f84 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -63,6 +63,7 @@ static int bcm47xxpart_parse(struct mtd_info *master, struct trx_header *trx; int trx_part = -1; int last_trx_part = -1; + int possible_nvram_sizes[] = { 0x8000, 0xF000, 0x10000, }; if (blocksize <= 0x10000) blocksize = 0x10000; @@ -99,13 +100,6 @@ static int bcm47xxpart_parse(struct mtd_info *master, continue; } - /* Standard NVRAM */ - if (buf[0x000 / 4] == NVRAM_HEADER) { - bcm47xxpart_add_part(&parts[curr_part++], "nvram", - offset, 0); - continue; - } - /* * board_data starts with board_id which differs across boards, * but we can use 'MPFR' (hopefully) magic at 0x100 @@ -174,6 +168,30 @@ static int bcm47xxpart_parse(struct mtd_info *master, continue; } } + + /* Look for NVRAM at the end of the last block. */ + for (i = 0; i < ARRAY_SIZE(possible_nvram_sizes); i++) { + if (curr_part > BCM47XXPART_MAX_PARTS) { + pr_warn("Reached maximum number of partitions, scanning stopped!\n"); + break; + } + + offset = master->size - possible_nvram_sizes[i]; + if (mtd_read(master, offset, 0x4, &bytes_read, + (uint8_t *)buf) < 0) { + pr_err("mtd_read error while reading at offset 0x%X!\n", + offset); + continue; + } + + /* Standard NVRAM */ + if (buf[0] == NVRAM_HEADER) { + bcm47xxpart_add_part(&parts[curr_part++], "nvram", + master->size - blocksize, 0); + break; + } + } + kfree(buf); /* -- cgit v1.2.3 From 84421b99cedc3443e76d2a594f3c815d5cb9a8e1 Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Fri, 8 Mar 2013 08:01:24 +0000 Subject: tg3: Update link_up flag for phylib devices Commit f4a46d1f46a8fece34edd2023e054072b02e110d introduced a bug where the ifconfig stats would remain 0 for phylib devices. This is due to tp->link_up flag never becoming true causing tg3_periodic_fetch_stats() to return. The link_up flag was being updated in tg3_test_and_report_link_chg() after setting up the phy. This function however, is not called for phylib devices since the driver does not do the phy setup. This patch moves the link_up flag update into the common tg3_link_report() function that gets called for phylib devices as well for non phylib devices when the link state changes. To avoid updating link_up twice, we replace tg3_carrier_...() calls that are followed by tg3_link_report(), with netif_carrier_...(). We can then remove the unused tg3_carrier_on() function. CC: Reported-by: OGAWA Hirofumi Signed-off-by: Nithin Nayak Sujir Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/tg3.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index fdb9b5655414..93729f942358 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -1869,6 +1869,8 @@ static void tg3_link_report(struct tg3 *tp) tg3_ump_link_report(tp); } + + tp->link_up = netif_carrier_ok(tp->dev); } static u16 tg3_advert_flowctrl_1000X(u8 flow_ctrl) @@ -2522,12 +2524,6 @@ static int tg3_phy_reset_5703_4_5(struct tg3 *tp) return err; } -static void tg3_carrier_on(struct tg3 *tp) -{ - netif_carrier_on(tp->dev); - tp->link_up = true; -} - static void tg3_carrier_off(struct tg3 *tp) { netif_carrier_off(tp->dev); @@ -2553,7 +2549,7 @@ static int tg3_phy_reset(struct tg3 *tp) return -EBUSY; if (netif_running(tp->dev) && tp->link_up) { - tg3_carrier_off(tp); + netif_carrier_off(tp->dev); tg3_link_report(tp); } @@ -4262,9 +4258,9 @@ static bool tg3_test_and_report_link_chg(struct tg3 *tp, int curr_link_up) { if (curr_link_up != tp->link_up) { if (curr_link_up) { - tg3_carrier_on(tp); + netif_carrier_on(tp->dev); } else { - tg3_carrier_off(tp); + netif_carrier_off(tp->dev); if (tp->phy_flags & TG3_PHYFLG_MII_SERDES) tp->phy_flags &= ~TG3_PHYFLG_PARALLEL_DETECT; } -- cgit v1.2.3 From 5f0fabf84d7b52f979dcbafa3d3c530c60d9a92c Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Thu, 7 Mar 2013 20:00:16 -0800 Subject: mwifiex: fix potential out-of-boundary access to ibss rate table smatch found this error: CHECK drivers/net/wireless/mwifiex/join.c drivers/net/wireless/mwifiex/join.c:1121 mwifiex_cmd_802_11_ad_hoc_join() error: testing array offset 'i' after use. Cc: # 3.0+ Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/join.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c index 246aa62a4817..2fe0ceba4400 100644 --- a/drivers/net/wireless/mwifiex/join.c +++ b/drivers/net/wireless/mwifiex/join.c @@ -1117,10 +1117,9 @@ mwifiex_cmd_802_11_ad_hoc_join(struct mwifiex_private *priv, adhoc_join->bss_descriptor.bssid, adhoc_join->bss_descriptor.ssid); - for (i = 0; bss_desc->supported_rates[i] && - i < MWIFIEX_SUPPORTED_RATES; - i++) - ; + for (i = 0; i < MWIFIEX_SUPPORTED_RATES && + bss_desc->supported_rates[i]; i++) + ; rates_size = i; /* Copy Data Rates from the Rates recorded in scan response */ -- cgit v1.2.3 From 664899786cb49cb52f620e06ac19c0be524a7cfa Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 27 Feb 2013 14:10:30 -0600 Subject: rtlwifi: rtl8192cu: Fix schedule while atomic bug splat When run at debug 3 or higher, rtl8192cu reports a BUG as follows: BUG: scheduling while atomic: kworker/u:0/5281/0x00000002 INFO: lockdep is turned off. Modules linked in: rtl8192cu rtl8192c_common rtlwifi fuse af_packet bnep bluetooth b43 mac80211 cfg80211 ipv6 snd_hda_codec_conexant kvm_amd k vm snd_hda_intel snd_hda_codec bcma rng_core snd_pcm ssb mmc_core snd_seq snd_timer snd_seq_device snd i2c_nforce2 sr_mod pcmcia forcedeth i2c_core soundcore cdrom sg serio_raw k8temp hwmon joydev ac battery pcmcia_core snd_page_alloc video button wmi autofs4 ext4 mbcache jbd2 crc16 thermal processor scsi_dh_alua scsi_dh_hp_sw scsi_dh_rdac scsi_dh_emc scsi_dh ata_generic pata_acpi pata_amd [last unloaded: rtlwifi] Pid: 5281, comm: kworker/u:0 Tainted: G W 3.8.0-wl+ #119 Call Trace: [] __schedule_bug+0x62/0x70 [] __schedule+0x730/0xa30 [] ? usb_hcd_link_urb_to_ep+0x19/0xa0 [] schedule+0x24/0x70 [] schedule_timeout+0x18c/0x2f0 [] ? wait_for_common+0x40/0x180 [] ? ehci_urb_enqueue+0xf1/0xee0 [] ? trace_hardirqs_on+0xd/0x10 [] wait_for_common+0xe5/0x180 [] ? try_to_wake_up+0x2d0/0x2d0 [] wait_for_completion_timeout+0xe/0x10 [] usb_start_wait_urb+0x8c/0x100 [] usb_control_msg+0xd9/0x130 [] _usb_read_sync+0xcd/0x140 [rtlwifi] [] _usb_read32_sync+0xe/0x10 [rtlwifi] [] rtl92cu_update_hal_rate_table+0x1a5/0x1f0 [rtl8192cu] The cause is a synchronous read from routine rtl92cu_update_hal_rate_table(). The resulting output is not critical, thus the debug statement is deleted. Reported-by: Jussi Kivilinna Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index b1ccff474c79..3c6e18c38e30 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -2058,8 +2058,6 @@ void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, (shortgi_rate << 4) | (shortgi_rate); } rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); - RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", - rtl_read_dword(rtlpriv, REG_ARFR0)); } void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, u8 rssi_level) -- cgit v1.2.3 From de88747f514a4e0cca416a8871de2302f4f77790 Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 3 Feb 2013 11:34:26 +0100 Subject: gpio: mvebu: Add clk support to prevent lockup The kirkwood SoC GPIO cores use the runit clock. Add code to clk_prepare_enable() runit, otherwise there is a danger of locking up the SoC by accessing the GPIO registers when runit clock is not ticking. Reported-by: Simon Baatz Signed-off-by: Andrew Lunn Tested-by: Simon Baatz Acked-by: Linus Walleij Cc: Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood.dtsi | 2 ++ drivers/gpio/gpio-mvebu.c | 7 +++++++ 2 files changed, 9 insertions(+) (limited to 'drivers') diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index 19709fbe12cf..cf8e8926a034 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -38,6 +38,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts = <35>, <36>, <37>, <38>; + clocks = <&gate_clk 7>; }; gpio1: gpio@10140 { @@ -49,6 +50,7 @@ interrupt-controller; #interrupt-cells = <2>; interrupts = <39>, <40>, <41>; + clocks = <&gate_clk 7>; }; serial@12000 { diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index 7472182967ce..61a6fde6c089 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c @@ -42,6 +42,7 @@ #include #include #include +#include #include /* @@ -496,6 +497,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev) struct resource *res; struct irq_chip_generic *gc; struct irq_chip_type *ct; + struct clk *clk; unsigned int ngpios; int soc_variant; int i, cpu, id; @@ -529,6 +531,11 @@ static int mvebu_gpio_probe(struct platform_device *pdev) return id; } + clk = devm_clk_get(&pdev->dev, NULL); + /* Not all SoCs require a clock.*/ + if (!IS_ERR(clk)) + clk_prepare_enable(clk); + mvchip->soc_variant = soc_variant; mvchip->chip.label = dev_name(&pdev->dev); mvchip->chip.dev = &pdev->dev; -- cgit v1.2.3 From 89c58c198b252f2bc20657fdd72a2aea788c435c Mon Sep 17 00:00:00 2001 From: Andrew Lunn Date: Sun, 3 Feb 2013 12:32:06 +0100 Subject: rtc: rtc-mv: Add support for clk to avoid lockups The Marvell RTC on Kirkwood makes use of the runit clock. Ensure the driver clk_prepare_enable() this clock, otherwise there is a danger the SoC will lockup when accessing RTC registers with the clock disabled. Reported-by: Simon Baatz Signed-off-by: Andrew Lunn Tested-by: Simon Baatz Cc: Signed-off-by: Jason Cooper --- arch/arm/boot/dts/kirkwood.dtsi | 1 + drivers/rtc/rtc-mv.c | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index cf8e8926a034..fada7e6d24d8 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi @@ -75,6 +75,7 @@ compatible = "marvell,kirkwood-rtc", "marvell,orion-rtc"; reg = <0x10300 0x20>; interrupts = <53>; + clocks = <&gate_clk 7>; }; spi@10600 { diff --git a/drivers/rtc/rtc-mv.c b/drivers/rtc/rtc-mv.c index 57233c885998..8f87fec27ce7 100644 --- a/drivers/rtc/rtc-mv.c +++ b/drivers/rtc/rtc-mv.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -41,6 +42,7 @@ struct rtc_plat_data { struct rtc_device *rtc; void __iomem *ioaddr; int irq; + struct clk *clk; }; static int mv_rtc_set_time(struct device *dev, struct rtc_time *tm) @@ -221,6 +223,7 @@ static int mv_rtc_probe(struct platform_device *pdev) struct rtc_plat_data *pdata; resource_size_t size; u32 rtc_time; + int ret = 0; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) @@ -239,11 +242,17 @@ static int mv_rtc_probe(struct platform_device *pdev) if (!pdata->ioaddr) return -ENOMEM; + pdata->clk = devm_clk_get(&pdev->dev, NULL); + /* Not all SoCs require a clock.*/ + if (!IS_ERR(pdata->clk)) + clk_prepare_enable(pdata->clk); + /* make sure the 24 hours mode is enabled */ rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); if (rtc_time & RTC_HOURS_12H_MODE) { dev_err(&pdev->dev, "24 Hours mode not supported.\n"); - return -EINVAL; + ret = -EINVAL; + goto out; } /* make sure it is actually functional */ @@ -252,7 +261,8 @@ static int mv_rtc_probe(struct platform_device *pdev) rtc_time = readl(pdata->ioaddr + RTC_TIME_REG_OFFS); if (rtc_time == 0x01000000) { dev_err(&pdev->dev, "internal RTC not ticking\n"); - return -ENODEV; + ret = -ENODEV; + goto out; } } @@ -268,8 +278,10 @@ static int mv_rtc_probe(struct platform_device *pdev) } else pdata->rtc = rtc_device_register(pdev->name, &pdev->dev, &mv_rtc_ops, THIS_MODULE); - if (IS_ERR(pdata->rtc)) - return PTR_ERR(pdata->rtc); + if (IS_ERR(pdata->rtc)) { + ret = PTR_ERR(pdata->rtc); + goto out; + } if (pdata->irq >= 0) { writel(0, pdata->ioaddr + RTC_ALARM_INTERRUPT_MASK_REG_OFFS); @@ -282,6 +294,11 @@ static int mv_rtc_probe(struct platform_device *pdev) } return 0; +out: + if (!IS_ERR(pdata->clk)) + clk_disable_unprepare(pdata->clk); + + return ret; } static int __exit mv_rtc_remove(struct platform_device *pdev) @@ -292,6 +309,9 @@ static int __exit mv_rtc_remove(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 0); rtc_device_unregister(pdata->rtc); + if (!IS_ERR(pdata->clk)) + clk_disable_unprepare(pdata->clk); + return 0; } -- cgit v1.2.3 From a40e7cf8f06b4e322ba902e4e9f6a6b0c2daa907 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Fri, 8 Mar 2013 12:43:32 -0800 Subject: dmi_scan: fix missing check for _DMI_ signature in smbios_present() Commit 9f9c9cbb6057 ("drivers/firmware/dmi_scan.c: fetch dmi version from SMBIOS if it exists") hoisted the check for "_DMI_" into dmi_scan_machine(), which means that we don't bother to check for "_DMI_" at offset 16 in an SMBIOS entry. smbios_present() may also call dmi_present() for an address where we found "_SM_", if it failed further validation. Check for "_DMI_" in smbios_present() before calling dmi_present(). [akpm@linux-foundation.org: fix build] Signed-off-by: Ben Hutchings Reported-by: Tim McGrath Tested-by: Tim Mcgrath Cc: Zhenzhong Duan Cc: Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/firmware/dmi_scan.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index 982f1f5f5742..4cd392dbf115 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -442,7 +442,6 @@ static int __init dmi_present(const char __iomem *p) static int __init smbios_present(const char __iomem *p) { u8 buf[32]; - int offset = 0; memcpy_fromio(buf, p, 32); if ((buf[5] < 32) && dmi_checksum(buf, buf[5])) { @@ -461,9 +460,9 @@ static int __init smbios_present(const char __iomem *p) dmi_ver = 0x0206; break; } - offset = 16; + return memcmp(p + 16, "_DMI_", 5) || dmi_present(p + 16); } - return dmi_present(buf + offset); + return 1; } void __init dmi_scan_machine(void) -- cgit v1.2.3 From 22dfab7fd7fd5a8a2c5556ca0a8fd35fc959abc8 Mon Sep 17 00:00:00 2001 From: Daniel Kurtz Date: Thu, 7 Mar 2013 19:43:33 -0800 Subject: Input: atmel_mxt_ts - Support for touchpad variant This same driver can be used by atmel based touchscreens and touchpads (buttonpads). Platform data may specify a device is a touchpad using the is_tp flag. This will cause the driver to perform some touchpad specific initializations, such as: * register input device name "Atmel maXTouch Touchpad" instead of Touchscreen. * register BTN_LEFT & BTN_TOOL_* event types. * register axis resolution (as a fixed constant, for now) * register BUTTONPAD property * process GPIO buttons using reportid T19 Input event GPIO mapping is done by the platform data key_map array. key_map[x] should contain the KEY or BTN code to send when processing GPIOx from T19. To specify a GPIO as not an input source, populate with KEY_RESERVED, or 0. Signed-off-by: Daniel Kurtz Signed-off-by: Benson Leung Signed-off-by: Nick Dyer Tested-by: Olof Johansson Signed-off-by: Linus Torvalds --- drivers/input/touchscreen/atmel_mxt_ts.c | 64 +++++++++++++++++++++++++++++++- include/linux/i2c/atmel_mxt_ts.h | 5 +++ 2 files changed, 67 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index d04f810cb1dd..8ed279c56d27 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -181,6 +181,12 @@ #define MXT_FWRESET_TIME 175 /* msec */ +/* MXT_SPT_GPIOPWM_T19 field */ +#define MXT_GPIO0_MASK 0x04 +#define MXT_GPIO1_MASK 0x08 +#define MXT_GPIO2_MASK 0x10 +#define MXT_GPIO3_MASK 0x20 + /* Command to unlock bootloader */ #define MXT_UNLOCK_CMD_MSB 0xaa #define MXT_UNLOCK_CMD_LSB 0xdc @@ -212,6 +218,8 @@ /* Touchscreen absolute values */ #define MXT_MAX_AREA 0xff +#define MXT_PIXELS_PER_MM 20 + struct mxt_info { u8 family_id; u8 variant_id; @@ -243,6 +251,8 @@ struct mxt_data { const struct mxt_platform_data *pdata; struct mxt_object *object_table; struct mxt_info info; + bool is_tp; + unsigned int irq; unsigned int max_x; unsigned int max_y; @@ -251,6 +261,7 @@ struct mxt_data { u8 T6_reportid; u8 T9_reportid_min; u8 T9_reportid_max; + u8 T19_reportid; }; static bool mxt_object_readable(unsigned int type) @@ -502,6 +513,21 @@ static int mxt_write_object(struct mxt_data *data, return mxt_write_reg(data->client, reg + offset, val); } +static void mxt_input_button(struct mxt_data *data, struct mxt_message *message) +{ + struct input_dev *input = data->input_dev; + bool button; + int i; + + /* Active-low switch */ + for (i = 0; i < MXT_NUM_GPIO; i++) { + if (data->pdata->key_map[i] == KEY_RESERVED) + continue; + button = !(message->message[0] & MXT_GPIO0_MASK << i); + input_report_key(input, data->pdata->key_map[i], button); + } +} + static void mxt_input_touchevent(struct mxt_data *data, struct mxt_message *message, int id) { @@ -585,6 +611,9 @@ static irqreturn_t mxt_interrupt(int irq, void *dev_id) int id = reportid - data->T9_reportid_min; mxt_input_touchevent(data, &message, id); update_input = true; + } else if (message.reportid == data->T19_reportid) { + mxt_input_button(data, &message); + update_input = true; } else { mxt_dump_message(dev, &message); } @@ -764,6 +793,9 @@ static int mxt_get_object_table(struct mxt_data *data) data->T9_reportid_min = min_id; data->T9_reportid_max = max_id; break; + case MXT_SPT_GPIOPWM_T19: + data->T19_reportid = min_id; + break; } } @@ -777,7 +809,7 @@ static void mxt_free_object_table(struct mxt_data *data) data->T6_reportid = 0; data->T9_reportid_min = 0; data->T9_reportid_max = 0; - + data->T19_reportid = 0; } static int mxt_initialize(struct mxt_data *data) @@ -1115,9 +1147,13 @@ static int mxt_probe(struct i2c_client *client, goto err_free_mem; } - input_dev->name = "Atmel maXTouch Touchscreen"; + data->is_tp = pdata && pdata->is_tp; + + input_dev->name = (data->is_tp) ? "Atmel maXTouch Touchpad" : + "Atmel maXTouch Touchscreen"; snprintf(data->phys, sizeof(data->phys), "i2c-%u-%04x/input0", client->adapter->nr, client->addr); + input_dev->phys = data->phys; input_dev->id.bustype = BUS_I2C; @@ -1140,6 +1176,29 @@ static int mxt_probe(struct i2c_client *client, __set_bit(EV_KEY, input_dev->evbit); __set_bit(BTN_TOUCH, input_dev->keybit); + if (data->is_tp) { + int i; + __set_bit(INPUT_PROP_POINTER, input_dev->propbit); + __set_bit(INPUT_PROP_BUTTONPAD, input_dev->propbit); + + for (i = 0; i < MXT_NUM_GPIO; i++) + if (pdata->key_map[i] != KEY_RESERVED) + __set_bit(pdata->key_map[i], input_dev->keybit); + + __set_bit(BTN_TOOL_FINGER, input_dev->keybit); + __set_bit(BTN_TOOL_DOUBLETAP, input_dev->keybit); + __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit); + __set_bit(BTN_TOOL_QUADTAP, input_dev->keybit); + __set_bit(BTN_TOOL_QUINTTAP, input_dev->keybit); + + input_abs_set_res(input_dev, ABS_X, MXT_PIXELS_PER_MM); + input_abs_set_res(input_dev, ABS_Y, MXT_PIXELS_PER_MM); + input_abs_set_res(input_dev, ABS_MT_POSITION_X, + MXT_PIXELS_PER_MM); + input_abs_set_res(input_dev, ABS_MT_POSITION_Y, + MXT_PIXELS_PER_MM); + } + /* For single touch */ input_set_abs_params(input_dev, ABS_X, 0, data->max_x, 0, 0); @@ -1258,6 +1317,7 @@ static SIMPLE_DEV_PM_OPS(mxt_pm_ops, mxt_suspend, mxt_resume); static const struct i2c_device_id mxt_id[] = { { "qt602240_ts", 0 }, { "atmel_mxt_ts", 0 }, + { "atmel_mxt_tp", 0 }, { "mXT224", 0 }, { } }; diff --git a/include/linux/i2c/atmel_mxt_ts.h b/include/linux/i2c/atmel_mxt_ts.h index f027f7a63511..99e379b74398 100644 --- a/include/linux/i2c/atmel_mxt_ts.h +++ b/include/linux/i2c/atmel_mxt_ts.h @@ -15,6 +15,9 @@ #include +/* For key_map array */ +#define MXT_NUM_GPIO 4 + /* Orient */ #define MXT_NORMAL 0x0 #define MXT_DIAGONAL 0x1 @@ -39,6 +42,8 @@ struct mxt_platform_data { unsigned int voltage; unsigned char orient; unsigned long irqflags; + bool is_tp; + const unsigned int key_map[MXT_NUM_GPIO]; }; #endif /* __LINUX_ATMEL_MXT_TS_H */ -- cgit v1.2.3 From 2ef392042debb86003e3e1d756960a2e53930b60 Mon Sep 17 00:00:00 2001 From: Benson Leung Date: Thu, 7 Mar 2013 19:43:34 -0800 Subject: Platform: x86: chromeos_laptop : Add basic platform data for atmel devices Add basic platform data to get the current upstream driver working with the 224s touchpad and 1664s touchscreen. We will be using NULL config so we will use the settings from the devices' NVRAMs. Signed-off-by: Benson Leung Tested-by: Olof Johansson Signed-off-by: Linus Torvalds --- drivers/platform/x86/chromeos_laptop.c | 41 ++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/platform/x86/chromeos_laptop.c b/drivers/platform/x86/chromeos_laptop.c index 93d66809355a..3e5b4497a1d0 100644 --- a/drivers/platform/x86/chromeos_laptop.c +++ b/drivers/platform/x86/chromeos_laptop.c @@ -23,6 +23,9 @@ #include #include +#include +#include +#include #include #define ATMEL_TP_I2C_ADDR 0x4b @@ -67,15 +70,49 @@ static struct i2c_board_info __initdata tsl2563_als_device = { I2C_BOARD_INFO("tsl2563", TAOS_ALS_I2C_ADDR), }; +static struct mxt_platform_data atmel_224s_tp_platform_data = { + .x_line = 18, + .y_line = 12, + .x_size = 102*20, + .y_size = 68*20, + .blen = 0x80, /* Gain setting is in upper 4 bits */ + .threshold = 0x32, + .voltage = 0, /* 3.3V */ + .orient = MXT_VERTICAL_FLIP, + .irqflags = IRQF_TRIGGER_FALLING, + .is_tp = true, + .key_map = { KEY_RESERVED, + KEY_RESERVED, + KEY_RESERVED, + BTN_LEFT }, + .config = NULL, + .config_length = 0, +}; + static struct i2c_board_info __initdata atmel_224s_tp_device = { I2C_BOARD_INFO("atmel_mxt_tp", ATMEL_TP_I2C_ADDR), - .platform_data = NULL, + .platform_data = &atmel_224s_tp_platform_data, .flags = I2C_CLIENT_WAKE, }; +static struct mxt_platform_data atmel_1664s_platform_data = { + .x_line = 32, + .y_line = 50, + .x_size = 1700, + .y_size = 2560, + .blen = 0x89, /* Gain setting is in upper 4 bits */ + .threshold = 0x28, + .voltage = 0, /* 3.3V */ + .orient = MXT_ROTATED_90_COUNTER, + .irqflags = IRQF_TRIGGER_FALLING, + .is_tp = false, + .config = NULL, + .config_length = 0, +}; + static struct i2c_board_info __initdata atmel_1664s_device = { I2C_BOARD_INFO("atmel_mxt_ts", ATMEL_TS_I2C_ADDR), - .platform_data = NULL, + .platform_data = &atmel_1664s_platform_data, .flags = I2C_CLIENT_WAKE, }; -- cgit v1.2.3 From e2f1a3bd8cdc046ece133a9e9ee6bd94727225b1 Mon Sep 17 00:00:00 2001 From: Nikola Pajkovsky Date: Tue, 26 Feb 2013 16:12:05 +0100 Subject: amd_iommu_init: remove __init from amd_iommu_erratum_746_workaround commit 318fe78 ("IOMMU, AMD Family15h Model10-1Fh erratum 746 Workaround") added amd_iommu_erratum_746_workaround and it's marked as __init, which is wrong WARNING: drivers/iommu/built-in.o(.text+0x639c): Section mismatch in reference from the function iommu_init_pci() to the function .init.text:amd_iommu_erratum_746_workaround() The function iommu_init_pci() references the function __init amd_iommu_erratum_746_workaround(). This is often because iommu_init_pci lacks a __init annotation or the annotation of amd_iommu_erratum_746_workaround is wrong. Signed-off-by: Nikola Pajkovsky Signed-off-by: Joerg Roedel --- drivers/iommu/amd_iommu_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index b6ecddb63cd0..e3c2d74b7684 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -980,7 +980,7 @@ static void __init free_iommu_all(void) * BIOS should disable L2B micellaneous clock gating by setting * L2_L2B_CK_GATE_CONTROL[CKGateL2BMiscDisable](D0F2xF4_x90[2]) = 1b */ -static void __init amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) +static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu) { u32 value; -- cgit v1.2.3 From ae1915892b4774655a5dc01039ce94efdff4b3fc Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 5 Mar 2013 23:16:48 +0100 Subject: iommu: OMAP: build only on OMAP2+ The OMAP IOMMU driver intentionally fails to build on OMAP1 platforms, so we should not allow enabling it there. Signed-off-by: Arnd Bergmann Cc: Joerg Roedel Cc: iommu@lists.linux-foundation.org Cc: Ohad Ben-Cohen Cc: Tony Lindgren Cc: Omar Ramirez Luna Acked-by: Tony Lindgren Signed-off-by: Joerg Roedel --- drivers/iommu/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index 5c514d0711d1..c332fb98480d 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -130,7 +130,7 @@ config IRQ_REMAP # OMAP IOMMU support config OMAP_IOMMU bool "OMAP IOMMU Support" - depends on ARCH_OMAP + depends on ARCH_OMAP2PLUS select IOMMU_API config OMAP_IOVMM -- cgit v1.2.3 From 8343bce195da8bb4d5a652ee085474a5cc62983f Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 9 Mar 2013 10:31:01 -0800 Subject: Atmel MXT touchscreen: increase reset timeouts There is a more complete atmel patch-series out by Nick Dyer that fixes this and other things, but in the meantime this is the minimal thing to get the touchscreen going on (at least my) Pixel Chromebook. Not that I want my dirty fingers near that beautiful screen, but it seems that a non-initialized touchscreen will also end up being a constant wakeup source, so you have to disable it to go to sleep. And it's easier to just fix the initialization sequence. Signed-off-by: Linus Torvalds --- drivers/input/touchscreen/atmel_mxt_ts.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c index 8ed279c56d27..59aa24002c7b 100644 --- a/drivers/input/touchscreen/atmel_mxt_ts.c +++ b/drivers/input/touchscreen/atmel_mxt_ts.c @@ -176,8 +176,8 @@ /* Define for MXT_GEN_COMMAND_T6 */ #define MXT_BOOT_VALUE 0xa5 #define MXT_BACKUP_VALUE 0x55 -#define MXT_BACKUP_TIME 25 /* msec */ -#define MXT_RESET_TIME 65 /* msec */ +#define MXT_BACKUP_TIME 50 /* msec */ +#define MXT_RESET_TIME 200 /* msec */ #define MXT_FWRESET_TIME 175 /* msec */ -- cgit v1.2.3 From 586948372189d33ceca9d89fb0c791ef4d53d8ad Mon Sep 17 00:00:00 2001 From: Stephan Frank Date: Thu, 7 Mar 2013 14:08:50 -0800 Subject: Input: wacom - add support for 0x10d It is a Wacom device found in Fujitsu Lifebook T902. Signed-off-by: Stephan Frank Acked-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- drivers/input/tablet/wacom_wac.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index 41b6fbf60112..1daa97913b7d 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c @@ -2017,6 +2017,9 @@ static const struct wacom_features wacom_features_0x100 = static const struct wacom_features wacom_features_0x101 = { "Wacom ISDv4 101", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; +static const struct wacom_features wacom_features_0x10D = + { "Wacom ISDv4 10D", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, + 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; static const struct wacom_features wacom_features_0x4001 = { "Wacom ISDv4 4001", WACOM_PKGLEN_MTTPC, 26202, 16325, 255, 0, MTTPC, WACOM_INTUOS_RES, WACOM_INTUOS_RES }; @@ -2201,6 +2204,7 @@ const struct usb_device_id wacom_ids[] = { { USB_DEVICE_WACOM(0xEF) }, { USB_DEVICE_WACOM(0x100) }, { USB_DEVICE_WACOM(0x101) }, + { USB_DEVICE_WACOM(0x10D) }, { USB_DEVICE_WACOM(0x4001) }, { USB_DEVICE_WACOM(0x47) }, { USB_DEVICE_WACOM(0xF4) }, -- cgit v1.2.3 From fef4c86e59a76f2ec1a77d5732f40752700bd5dd Mon Sep 17 00:00:00 2001 From: David Oostdyk Date: Fri, 8 Mar 2013 08:28:15 +0000 Subject: rrunner.c: fix possible memory leak in rr_init_one() In the event that register_netdev() failed, the rrpriv->evt_ring allocation would have not been freed. Signed-off-by: David Oostdyk Signed-off-by: David S. Miller --- drivers/net/hippi/rrunner.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/hippi/rrunner.c b/drivers/net/hippi/rrunner.c index e5b19b056909..3c4d6274bb9b 100644 --- a/drivers/net/hippi/rrunner.c +++ b/drivers/net/hippi/rrunner.c @@ -202,6 +202,9 @@ static int rr_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return 0; out: + if (rrpriv->evt_ring) + pci_free_consistent(pdev, EVT_RING_SIZE, rrpriv->evt_ring, + rrpriv->evt_ring_dma); if (rrpriv->rx_ring) pci_free_consistent(pdev, RX_TOTAL_SIZE, rrpriv->rx_ring, rrpriv->rx_ring_dma); -- cgit v1.2.3 From 94f54f5336aac6801f2a14dcb12467e41b35456a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 5 Mar 2013 22:26:06 +1000 Subject: drm/nv50: encoder creation failure doesn't mean full init failure It's meant as a notification only, not a fatal error. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 87a5a56ed358..2db57990f65c 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -2276,6 +2276,7 @@ nv50_display_create(struct drm_device *dev) NV_WARN(drm, "failed to create encoder %d/%d/%d: %d\n", dcbe->location, dcbe->type, ffs(dcbe->or) - 1, ret); + ret = 0; } } -- cgit v1.2.3 From c8f28f89566321842afb81d3ddd79d611e3587ce Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 5 Mar 2013 14:59:26 +0100 Subject: drm/nouveau: fix regression in vblanking nv50_vblank_enable/disable got switched from NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_0 (4) << head to 1 << head, which is wrong. 4 << head is the correct value. Fixes regression with vblanking since 1d7c71a3e2f77 "drm/nouveau/disp: port vblank handling to event interface" Signed-off-by: Maarten Lankhorst Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 5fa13267bd9f..02e369f80449 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -544,13 +544,13 @@ nv50_disp_curs_ofuncs = { static void nv50_disp_base_vblank_enable(struct nouveau_event *event, int head) { - nv_mask(event->priv, 0x61002c, (1 << head), (1 << head)); + nv_mask(event->priv, 0x61002c, (4 << head), (4 << head)); } static void nv50_disp_base_vblank_disable(struct nouveau_event *event, int head) { - nv_mask(event->priv, 0x61002c, (1 << head), (0 << head)); + nv_mask(event->priv, 0x61002c, (4 << head), 0); } static int -- cgit v1.2.3 From 2b77c1c01b556045c451f034389932efb5b71c58 Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 3 Mar 2013 18:58:45 +0100 Subject: drm/nouveau: idle channel before releasing notify object Unmapping it while it's still in use (e.g. by M2MF) can lead to page faults and a lot of TRAP_M2MF spam in dmesg. Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_abi16.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 41241922263f..3b6dc883e150 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -116,6 +116,11 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, { struct nouveau_abi16_ntfy *ntfy, *temp; + /* wait for all activity to stop before releasing notify object, which + * may be still in use */ + if (chan->chan && chan->ntfy) + nouveau_channel_idle(chan->chan); + /* cleanup notifier state */ list_for_each_entry_safe(ntfy, temp, &chan->notifiers, head) { nouveau_abi16_ntfy_fini(chan, ntfy); -- cgit v1.2.3 From c1b90df22595441d3a0ae86bd7c3bcc32787950a Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Sun, 3 Mar 2013 13:32:00 +0100 Subject: drm/nv50: use correct tiling methods for m2mf buffer moves Currently used only on original nv50, nvaa and nvac. Signed-off-by: Marcin Slusarz Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 11ca82148edc..7ff10711a4d0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -801,7 +801,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, stride = 16 * 4; height = amount / stride; - if (new_mem->mem_type == TTM_PL_VRAM && + if (old_mem->mem_type == TTM_PL_VRAM && nouveau_bo_tile_layout(nvbo)) { ret = RING_SPACE(chan, 8); if (ret) @@ -823,7 +823,7 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, BEGIN_NV04(chan, NvSubCopy, 0x0200, 1); OUT_RING (chan, 1); } - if (old_mem->mem_type == TTM_PL_VRAM && + if (new_mem->mem_type == TTM_PL_VRAM && nouveau_bo_tile_layout(nvbo)) { ret = RING_SPACE(chan, 8); if (ret) -- cgit v1.2.3 From 39735019716e93914a366ac1fb2e78f91b170545 Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Sat, 9 Mar 2013 16:17:20 -0800 Subject: Input: tc3589x-keypad - fix keymap size The keymap size used by tc3589x is too low, leading to the driver overwriting other people's memory. Fix this by making the driver use the automatically allocated keymap provided by matrix_keypad_build_keymap() instead of allocating one on its own. Signed-off-by: Rabin Vincent Signed-off-by: Dmitry Torokhov --- drivers/input/keyboard/tc3589x-keypad.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/input/keyboard/tc3589x-keypad.c b/drivers/input/keyboard/tc3589x-keypad.c index 2fb0d76a04c4..208de7cbb7fa 100644 --- a/drivers/input/keyboard/tc3589x-keypad.c +++ b/drivers/input/keyboard/tc3589x-keypad.c @@ -70,8 +70,6 @@ #define TC3589x_EVT_INT_CLR 0x2 #define TC3589x_KBD_INT_CLR 0x1 -#define TC3589x_KBD_KEYMAP_SIZE 64 - /** * struct tc_keypad - data structure used by keypad driver * @tc3589x: pointer to tc35893 @@ -88,7 +86,7 @@ struct tc_keypad { const struct tc3589x_keypad_platform_data *board; unsigned int krow; unsigned int kcol; - unsigned short keymap[TC3589x_KBD_KEYMAP_SIZE]; + unsigned short *keymap; bool keypad_stopped; }; @@ -338,12 +336,14 @@ static int tc3589x_keypad_probe(struct platform_device *pdev) error = matrix_keypad_build_keymap(plat->keymap_data, NULL, TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, - keypad->keymap, input); + NULL, input); if (error) { dev_err(&pdev->dev, "Failed to build keymap\n"); goto err_free_mem; } + keypad->keymap = input->keycode; + input_set_capability(input, EV_MSC, MSC_SCAN); if (!plat->no_autorepeat) __set_bit(EV_REP, input->evbit); -- cgit v1.2.3 From f94352f8db97b9a3b3c1ec45f6fef1400880168a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 3 Mar 2013 20:19:07 -0800 Subject: Input: ads7864 - check return value of regulator enable At least print a warning if we can't power the device up. Signed-off-by: Mark Brown Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/ads7846.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/ads7846.c b/drivers/input/touchscreen/ads7846.c index 4f702b3ec1a3..434c3df250ca 100644 --- a/drivers/input/touchscreen/ads7846.c +++ b/drivers/input/touchscreen/ads7846.c @@ -236,7 +236,12 @@ static void __ads7846_disable(struct ads7846 *ts) /* Must be called with ts->lock held */ static void __ads7846_enable(struct ads7846 *ts) { - regulator_enable(ts->reg); + int error; + + error = regulator_enable(ts->reg); + if (error != 0) + dev_err(&ts->spi->dev, "Failed to enable supply: %d\n", error); + ads7846_restart(ts); } -- cgit v1.2.3 From 4b7d293c64fde133cc2b669d0d7637b8a4c6d62f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 3 Mar 2013 20:21:30 -0800 Subject: Input: mms114 - Fix regulator enable and disable paths When it uses regulators the mms114 driver checks to see if it managed to acquire regulators and ignores errors. This is not the intended usage and not great style in general. Since the driver already refuses to probe if it fails to allocate the regulators simply make the enable and disable calls unconditional and add appropriate error handling, including adding cleanup of the regulators if setup_reg() fails. Signed-off-by: Mark Brown Acked-by: Joonyoung Shim Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/mms114.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/input/touchscreen/mms114.c b/drivers/input/touchscreen/mms114.c index 4a29ddf6bf1e..1443532fe6c4 100644 --- a/drivers/input/touchscreen/mms114.c +++ b/drivers/input/touchscreen/mms114.c @@ -314,15 +314,27 @@ static int mms114_start(struct mms114_data *data) struct i2c_client *client = data->client; int error; - if (data->core_reg) - regulator_enable(data->core_reg); - if (data->io_reg) - regulator_enable(data->io_reg); + error = regulator_enable(data->core_reg); + if (error) { + dev_err(&client->dev, "Failed to enable avdd: %d\n", error); + return error; + } + + error = regulator_enable(data->io_reg); + if (error) { + dev_err(&client->dev, "Failed to enable vdd: %d\n", error); + regulator_disable(data->core_reg); + return error; + } + mdelay(MMS114_POWERON_DELAY); error = mms114_setup_regs(data); - if (error < 0) + if (error < 0) { + regulator_disable(data->io_reg); + regulator_disable(data->core_reg); return error; + } if (data->pdata->cfg_pin) data->pdata->cfg_pin(true); @@ -335,16 +347,20 @@ static int mms114_start(struct mms114_data *data) static void mms114_stop(struct mms114_data *data) { struct i2c_client *client = data->client; + int error; disable_irq(client->irq); if (data->pdata->cfg_pin) data->pdata->cfg_pin(false); - if (data->io_reg) - regulator_disable(data->io_reg); - if (data->core_reg) - regulator_disable(data->core_reg); + error = regulator_disable(data->io_reg); + if (error) + dev_warn(&client->dev, "Failed to disable vdd: %d\n", error); + + error = regulator_disable(data->core_reg); + if (error) + dev_warn(&client->dev, "Failed to disable avdd: %d\n", error); } static int mms114_input_open(struct input_dev *dev) -- cgit v1.2.3 From aaaf9cf71c43f42285f2b1a5b54c9306f3cc3150 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Wed, 6 Feb 2013 17:23:50 +0100 Subject: drivers/i2c: remove !S390 dependency, add missing GENERIC_HARDIRQS dependencies Remove !S390 dependency from i2c Kconfig, since s390 now supports PCI, HAS_IOMEM and HAS_DMA, however we need to add a couple of GENERIC_HARDIRQS dependecies to fix compile and link errors like these: ERROR: "devm_request_threaded_irq" [drivers/i2c/i2c-smbus.ko] undefined! ERROR: "devm_request_threaded_irq" [drivers/i2c/busses/i2c-ocores.ko] undefined! Cc: Wolfram Sang Cc: Jean Delvare Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- drivers/i2c/Kconfig | 2 +- drivers/i2c/busses/Kconfig | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 46cde098c11c..e380c6eef3af 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -4,7 +4,6 @@ menuconfig I2C tristate "I2C support" - depends on !S390 select RT_MUTEXES ---help--- I2C (pronounce: I-squared-C) is a slow serial bus protocol used in @@ -76,6 +75,7 @@ config I2C_HELPER_AUTO config I2C_SMBUS tristate "SMBus-specific protocols" if !I2C_HELPER_AUTO + depends on GENERIC_HARDIRQS help Say Y here if you want support for SMBus extensions to the I2C specification. At the moment, the only supported extension is diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a3725de92384..adfee98486b1 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -114,7 +114,7 @@ config I2C_I801 config I2C_ISCH tristate "Intel SCH SMBus 1.0" - depends on PCI + depends on PCI && GENERIC_HARDIRQS select LPC_SCH help Say Y here if you want to use SMBus controller on the Intel SCH @@ -543,6 +543,7 @@ config I2C_NUC900 config I2C_OCORES tristate "OpenCores I2C Controller" + depends on GENERIC_HARDIRQS help If you say yes to this option, support will be included for the OpenCores I2C controller. For details see @@ -777,7 +778,7 @@ config I2C_DIOLAN_U2C config I2C_PARPORT tristate "Parallel port adapter" - depends on PARPORT + depends on PARPORT && GENERIC_HARDIRQS select I2C_ALGOBIT select I2C_SMBUS help @@ -802,6 +803,7 @@ config I2C_PARPORT config I2C_PARPORT_LIGHT tristate "Parallel port adapter (light)" + depends on GENERIC_HARDIRQS select I2C_ALGOBIT select I2C_SMBUS help -- cgit v1.2.3 From 52319b457cd78aa891f5947cf2237dd5f6a4c52d Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Fri, 8 Mar 2013 09:29:34 +0100 Subject: s390/kdump: Do not add standby memory for kdump Standby memory that is located outside [0,OLDMEM_SIZE] is currently used by the s390 memory detection. This leads to additional memory consumption due to allocation of page structures. To fix this, we now do not add standby memory if the kernel is started in kdump mode. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky --- drivers/s390/char/sclp_cmd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 30a2255389e5..cd798386b622 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -627,6 +627,8 @@ static int __init sclp_detect_standby_memory(void) struct read_storage_sccb *sccb; int i, id, assigned, rc; + if (OLDMEM_BASE) /* No standby memory in kdump mode */ + return 0; if (!early_read_info_sccb_valid) return 0; if ((sclp_facilities & 0xe00000000000ULL) != 0xe00000000000ULL) -- cgit v1.2.3 From 66e4afc77f76653460d7eb31ec793506ada1ad33 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Mar 2013 12:40:31 +0200 Subject: usb: gadget: pxa25x: fix disconnect reporting when commit 6166c24 (usb: gadget: pxa25x_udc: convert to udc_start/udc_stop) converted this driver to udc_start/udc_stop, it failed to consider the fact that stop_activity() is called from disconnect interrupt. Fix the problem so that gadget drivers know about proper disconnect sequences. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/pxa25x_udc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 9aa9dd5168d8..d0f37484b6b0 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c @@ -1303,6 +1303,10 @@ stop_activity(struct pxa25x_udc *dev, struct usb_gadget_driver *driver) } del_timer_sync(&dev->timer); + /* report disconnect; the driver is already quiesced */ + if (driver) + driver->disconnect(&dev->gadget); + /* re-init driver-visible data structures */ udc_reinit(dev); } -- cgit v1.2.3 From f0e68fc3caf677e834f7bd0f601800e686b56c98 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 22 Feb 2013 13:22:39 +0000 Subject: thermal: rcar: fix missing unlock on error in rcar_thermal_update_temp() Add the missing unlock before return from function rcar_thermal_update_temp() in the error handling case. Signed-off-by: Wei Yongjun Acked-by: Kuninori Morimoto Signed-off-by: Zhang Rui --- drivers/thermal/rcar_thermal.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 28f091994013..04a5566b1723 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -145,6 +145,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) struct device *dev = rcar_priv_to_dev(priv); int i; int ctemp, old, new; + int ret = -EINVAL; mutex_lock(&priv->lock); @@ -174,7 +175,7 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) if (!ctemp) { dev_err(dev, "thermal sensor was broken\n"); - return -EINVAL; + goto err_out_unlock; } /* @@ -192,10 +193,10 @@ static int rcar_thermal_update_temp(struct rcar_thermal_priv *priv) dev_dbg(dev, "thermal%d %d -> %d\n", priv->id, priv->ctemp, ctemp); priv->ctemp = ctemp; - + ret = 0; +err_out_unlock: mutex_unlock(&priv->lock); - - return 0; + return ret; } static int rcar_thermal_get_temp(struct thermal_zone_device *zone, -- cgit v1.2.3 From 6bc51b662241738ac292ffa021b345c2aa604230 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 06:45:32 +0000 Subject: Thermal: dove: 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 Cc: Andrew Lunn Reviewed-by: Thierry Reding Signed-off-by: Zhang Rui --- drivers/thermal/dove_thermal.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c index 7b0bfa0e7a9c..3078c403b42d 100644 --- a/drivers/thermal/dove_thermal.c +++ b/drivers/thermal/dove_thermal.c @@ -143,22 +143,18 @@ static int dove_thermal_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->sensor = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->sensor) { - dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); - return -EADDRNOTAVAIL; - } + priv->sensor = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->sensor)) + return PTR_ERR(priv->sensor); res = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res) { dev_err(&pdev->dev, "Failed to get platform resource\n"); return -ENODEV; } - priv->control = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->control) { - dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); - return -EADDRNOTAVAIL; - } + priv->control = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->control)) + return PTR_ERR(priv->control); ret = dove_init_sensor(priv); if (ret) { -- cgit v1.2.3 From 5095526faf38472bf04af919797a1f01a0ccb558 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 06:45:33 +0000 Subject: Thermal: rcar: 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 Cc: Kuninori Morimoto Reviewed-by: Thierry Reding Signed-off-by: Zhang Rui --- drivers/thermal/rcar_thermal.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index 04a5566b1723..ab518140207d 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -400,11 +400,9 @@ static int rcar_thermal_probe(struct platform_device *pdev) /* * rcar_has_irq_support() will be enabled */ - common->base = devm_request_and_ioremap(dev, res); - if (!common->base) { - dev_err(dev, "Unable to ioremap thermal register\n"); - return -ENOMEM; - } + common->base = devm_ioremap_resource(dev, res); + if (IS_ERR(common->base)) + return PTR_ERR(common->base); /* enable temperature comparation */ rcar_thermal_common_write(common, ENR, 0x00030303); @@ -423,11 +421,9 @@ static int rcar_thermal_probe(struct platform_device *pdev) return -ENOMEM; } - priv->base = devm_request_and_ioremap(dev, res); - if (!priv->base) { - dev_err(dev, "Unable to ioremap priv register\n"); - return -ENOMEM; - } + priv->base = devm_ioremap_resource(dev, res); + if (IS_ERR(priv->base)) + return PTR_ERR(priv->base); priv->common = common; priv->id = i; -- cgit v1.2.3 From aa3b5d222da5922ab1883eba3e9d8f92ad148155 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Mon, 4 Mar 2013 06:45:34 +0000 Subject: Thermal: kirkwood: 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 Cc: Nobuhiro Iwamatsu Reviewed-by: Thierry Reding Acked-by: Nobuhiro Iwamatsu Signed-off-by: Zhang Rui --- drivers/thermal/kirkwood_thermal.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c index 65cb4f09e8f6..e5500edb5285 100644 --- a/drivers/thermal/kirkwood_thermal.c +++ b/drivers/thermal/kirkwood_thermal.c @@ -85,11 +85,9 @@ static int kirkwood_thermal_probe(struct platform_device *pdev) if (!priv) return -ENOMEM; - priv->sensor = devm_request_and_ioremap(&pdev->dev, res); - if (!priv->sensor) { - dev_err(&pdev->dev, "Failed to request_ioremap memory\n"); - return -EADDRNOTAVAIL; - } + priv->sensor = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(priv->sensor)) + return PTR_ERR(priv->sensor); thermal = thermal_zone_device_register("kirkwood_thermal", 0, 0, priv, &ops, NULL, 0, 0); -- cgit v1.2.3 From fb84d9907f0ff0e3f7d70d55039ddf0f78d2a472 Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 4 Mar 2013 16:52:47 +0000 Subject: thermal: rcar_thermal: propagate return value of thermal_zone_device_register thermal_zone_device_register returns a value contained in the pointer itself use PTR_ERR to obtain the address and return it at the end. Signed-off-by: Devendra Naga Signed-off-by: Zhang Rui --- drivers/thermal/rcar_thermal.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c index ab518140207d..2cc5b6115e3e 100644 --- a/drivers/thermal/rcar_thermal.c +++ b/drivers/thermal/rcar_thermal.c @@ -364,6 +364,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) struct resource *res, *irq; int mres = 0; int i; + int ret = -ENODEV; int idle = IDLE_INTERVAL; common = devm_kzalloc(dev, sizeof(*common), GFP_KERNEL); @@ -438,6 +439,7 @@ static int rcar_thermal_probe(struct platform_device *pdev) idle); if (IS_ERR(priv->zone)) { dev_err(dev, "can't register thermal zone\n"); + ret = PTR_ERR(priv->zone); goto error_unregister; } @@ -457,7 +459,7 @@ error_unregister: rcar_thermal_for_each_priv(priv, common) thermal_zone_device_unregister(priv->zone); - return -ENODEV; + return ret; } static int rcar_thermal_remove(struct platform_device *pdev) -- cgit v1.2.3 From 043e4652bf3378883e7c0db38fa47fa8e2558f9c Mon Sep 17 00:00:00 2001 From: Devendra Naga Date: Mon, 4 Mar 2013 16:52:48 +0000 Subject: thermal: exynos_thermal: return a proper error code while thermal_zone_device_register fail. we are returning EINVAL while the thermal_zone_device_register function fail. instead we can use the return value from the thermal_zone_device_register by using PTR_ERR. Signed-off-by: Devendra Naga Signed-off-by: Zhang Rui --- drivers/thermal/exynos_thermal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/thermal/exynos_thermal.c b/drivers/thermal/exynos_thermal.c index e04ebd8671ac..46568c078dee 100644 --- a/drivers/thermal/exynos_thermal.c +++ b/drivers/thermal/exynos_thermal.c @@ -476,7 +476,7 @@ static int exynos_register_thermal(struct thermal_sensor_conf *sensor_conf) if (IS_ERR(th_zone->therm_dev)) { pr_err("Failed to register thermal zone device\n"); - ret = -EINVAL; + ret = PTR_ERR(th_zone->therm_dev); goto err_unregister; } th_zone->mode = THERMAL_DEVICE_ENABLED; -- cgit v1.2.3 From be3101c23394af59694c8a2aae6d07f5da62fea5 Mon Sep 17 00:00:00 2001 From: "Matwey V. Kornilov" Date: Sat, 9 Mar 2013 13:57:32 +0400 Subject: usb: cp210x new Vendor/Device IDs This patch adds support for the Lake Shore Cryotronics devices to the CP210x driver. These lines are ported from cp210x driver distributed by Lake Shore web site: http://www.lakeshore.com/Documents/Lake%20Shore%20cp210x-3.0.0.tar.gz and licensed under the terms of GPLv2. Moreover, I've tested this changes with Lake Shore 335 in my labs. Signed-off-by: Matwey V. Kornilov Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index edc0f0dcad83..67088cebaa1d 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -150,6 +150,25 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x1BE3, 0x07A6) }, /* WAGO 750-923 USB Service Cable */ { USB_DEVICE(0x1E29, 0x0102) }, /* Festo CPX-USB */ { USB_DEVICE(0x1E29, 0x0501) }, /* Festo CMSP */ + { USB_DEVICE(0x1FB9, 0x0100) }, /* Lake Shore Model 121 Current Source */ + { USB_DEVICE(0x1FB9, 0x0200) }, /* Lake Shore Model 218A Temperature Monitor */ + { USB_DEVICE(0x1FB9, 0x0201) }, /* Lake Shore Model 219 Temperature Monitor */ + { USB_DEVICE(0x1FB9, 0x0202) }, /* Lake Shore Model 233 Temperature Transmitter */ + { USB_DEVICE(0x1FB9, 0x0203) }, /* Lake Shore Model 235 Temperature Transmitter */ + { USB_DEVICE(0x1FB9, 0x0300) }, /* Lake Shore Model 335 Temperature Controller */ + { USB_DEVICE(0x1FB9, 0x0301) }, /* Lake Shore Model 336 Temperature Controller */ + { USB_DEVICE(0x1FB9, 0x0302) }, /* Lake Shore Model 350 Temperature Controller */ + { USB_DEVICE(0x1FB9, 0x0303) }, /* Lake Shore Model 371 AC Bridge */ + { USB_DEVICE(0x1FB9, 0x0400) }, /* Lake Shore Model 411 Handheld Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0401) }, /* Lake Shore Model 425 Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0402) }, /* Lake Shore Model 455A Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0403) }, /* Lake Shore Model 475A Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0404) }, /* Lake Shore Model 465 Three Axis Gaussmeter */ + { USB_DEVICE(0x1FB9, 0x0600) }, /* Lake Shore Model 625A Superconducting MPS */ + { USB_DEVICE(0x1FB9, 0x0601) }, /* Lake Shore Model 642A Magnet Power Supply */ + { USB_DEVICE(0x1FB9, 0x0602) }, /* Lake Shore Model 648 Magnet Power Supply */ + { USB_DEVICE(0x1FB9, 0x0700) }, /* Lake Shore Model 737 VSM Controller */ + { USB_DEVICE(0x1FB9, 0x0701) }, /* Lake Shore Model 776 Hall Matrix */ { USB_DEVICE(0x3195, 0xF190) }, /* Link Instruments MSO-19 */ { USB_DEVICE(0x3195, 0xF280) }, /* Link Instruments MSO-28 */ { USB_DEVICE(0x3195, 0xF281) }, /* Link Instruments MSO-28 */ -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 6987a6dabfc40222ef767f67b57212fe3a0225fb Mon Sep 17 00:00:00 2001 From: Malcolm Priestley Date: Mon, 18 Feb 2013 19:54:18 +0000 Subject: staging: vt6656: Fix oops on resume from suspend. Remove usb_put_dev from vt6656_suspend and usb_get_dev from vt6566_resume. These are not normally in suspend/resume functions. Signed-off-by: Malcolm Priestley Cc: stable@vger.kernel.org # 3.0+ Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/main_usb.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index d5f53e1a74a2..a5063a6f64d9 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -669,8 +669,6 @@ static int vt6656_suspend(struct usb_interface *intf, pm_message_t message) if (device->flags & DEVICE_FLAGS_OPENED) device_close(device->dev); - usb_put_dev(interface_to_usbdev(intf)); - return 0; } @@ -681,8 +679,6 @@ static int vt6656_resume(struct usb_interface *intf) if (!device || !device->dev) return -ENODEV; - usb_get_dev(interface_to_usbdev(intf)); - if (!(device->flags & DEVICE_FLAGS_OPENED)) device_open(device->dev); -- cgit v1.2.3 From d49c3d61cfdb33165d2760817ec9601d277575d4 Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Fri, 22 Feb 2013 10:07:03 -0800 Subject: staging: comedi: drivers: usbdux.c: fix DMA buffers on stack fix for instances of DMA buffer on stack(being passed to usb_control_msg) for the USB-DUX-D Board driver. Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1a0062a04456..6aac1f60bc42 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -730,10 +730,14 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) static int usbduxsub_start(struct usbduxsub *usbduxsub) { int errcode = 0; - uint8_t local_transfer_buffer[16]; + uint8_t *local_transfer_buffer; + + local_transfer_buffer = kmalloc(1, GFP_KERNEL); + if (!local_transfer_buffer) + return -ENOMEM; /* 7f92 to zero */ - local_transfer_buffer[0] = 0; + *local_transfer_buffer = 0; errcode = usb_control_msg(usbduxsub->usbdev, /* create a pipe for a control transfer */ usb_sndctrlpipe(usbduxsub->usbdev, 0), @@ -751,22 +755,25 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) { + if (errcode < 0) dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (start)\n"); - return errcode; - } - return 0; + + kfree(local_transfer_buffer); + return errcode; } static int usbduxsub_stop(struct usbduxsub *usbduxsub) { int errcode = 0; + uint8_t *local_transfer_buffer; - uint8_t local_transfer_buffer[16]; + local_transfer_buffer = kmalloc(1, GFP_KERNEL); + if (!local_transfer_buffer) + return -ENOMEM; /* 7f92 to one */ - local_transfer_buffer[0] = 1; + *local_transfer_buffer = 1; errcode = usb_control_msg(usbduxsub->usbdev, usb_sndctrlpipe(usbduxsub->usbdev, 0), /* bRequest, "Firmware" */ @@ -781,12 +788,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) { + if (errcode < 0) dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (stop)\n"); - return errcode; - } - return 0; + + kfree(local_transfer_buffer); + return errcode; } static int usbduxsub_upload(struct usbduxsub *usbduxsub, -- cgit v1.2.3 From 161f440c8d915181b34f5a64f52a543beca6b1e9 Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Fri, 22 Feb 2013 10:07:30 -0800 Subject: staging: comedi: drivers: usbduxfast.c: fix for DMA buffers on stack fix for instances of DMA buffer on stack(being passed to usb_control_msg) for the USB-DUXfast Board driver. Signed-off-by: Kumar Amit Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxfast.c | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index 4bf5dd094dc9..1ba0e3df492d 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c @@ -436,10 +436,14 @@ static void usbduxfastsub_ai_Irq(struct urb *urb) static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) { int ret; - unsigned char local_transfer_buffer[16]; + unsigned char *local_transfer_buffer; + + local_transfer_buffer = kmalloc(1, GFP_KERNEL); + if (!local_transfer_buffer) + return -ENOMEM; /* 7f92 to zero */ - local_transfer_buffer[0] = 0; + *local_transfer_buffer = 0; /* bRequest, "Firmware" */ ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, @@ -450,22 +454,25 @@ static int usbduxfastsub_start(struct usbduxfastsub_s *udfs) local_transfer_buffer, 1, /* Length */ EZTIMEOUT); /* Timeout */ - if (ret < 0) { + if (ret < 0) dev_err(&udfs->interface->dev, "control msg failed (start)\n"); - return ret; - } - return 0; + kfree(local_transfer_buffer); + return ret; } static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) { int ret; - unsigned char local_transfer_buffer[16]; + unsigned char *local_transfer_buffer; + + local_transfer_buffer = kmalloc(1, GFP_KERNEL); + if (!local_transfer_buffer) + return -ENOMEM; /* 7f92 to one */ - local_transfer_buffer[0] = 1; + *local_transfer_buffer = 1; /* bRequest, "Firmware" */ ret = usb_control_msg(udfs->usbdev, usb_sndctrlpipe(udfs->usbdev, 0), USBDUXFASTSUB_FIRMWARE, @@ -474,13 +481,12 @@ static int usbduxfastsub_stop(struct usbduxfastsub_s *udfs) 0x0000, /* Index */ local_transfer_buffer, 1, /* Length */ EZTIMEOUT); /* Timeout */ - if (ret < 0) { + if (ret < 0) dev_err(&udfs->interface->dev, "control msg failed (stop)\n"); - return ret; - } - return 0; + kfree(local_transfer_buffer); + return ret; } static int usbduxfastsub_upload(struct usbduxfastsub_s *udfs, -- cgit v1.2.3 From 47b1be5c0f4ed4991f3d956dbd7ba69cb5bc521f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Wed, 20 Feb 2013 10:57:01 +0800 Subject: staging: imx/drm: request irq only after adding the crtc If the bootloader already enabled the display, the interrupt handler will be called as soon as it is registered. If the CRTC is not already added at this time, the call to imx_drm_handle_vblank will result in a NULL pointer dereference. The patch fixes a kernel panic [1], which has been on linux-next since Jan 8 [2]. [1] http://thread.gmane.org/gmane.linux.ports.arm.kernel/218858 [2] http://thread.gmane.org/gmane.linux.ports.arm.kernel/208192 Signed-off-by: Philipp Zabel Tested-by: Shawn Guo Signed-off-by: Greg Kroah-Hartman --- drivers/staging/imx-drm/ipuv3-crtc.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/imx-drm/ipuv3-crtc.c b/drivers/staging/imx-drm/ipuv3-crtc.c index 4b3a019409b5..b028b0d1317b 100644 --- a/drivers/staging/imx-drm/ipuv3-crtc.c +++ b/drivers/staging/imx-drm/ipuv3-crtc.c @@ -483,17 +483,6 @@ static int ipu_get_resources(struct ipu_crtc *ipu_crtc, goto err_out; } - ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, - IPU_IRQ_EOF); - ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, - "imx_drm", ipu_crtc); - if (ret < 0) { - dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); - goto err_out; - } - - disable_irq(ipu_crtc->irq); - return 0; err_out: ipu_put_resources(ipu_crtc); @@ -504,6 +493,7 @@ err_out: static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, struct ipu_client_platformdata *pdata) { + struct ipu_soc *ipu = dev_get_drvdata(ipu_crtc->dev->parent); int ret; ret = ipu_get_resources(ipu_crtc, pdata); @@ -522,6 +512,17 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc, goto err_put_resources; } + ipu_crtc->irq = ipu_idmac_channel_irq(ipu, ipu_crtc->ipu_ch, + IPU_IRQ_EOF); + ret = devm_request_irq(ipu_crtc->dev, ipu_crtc->irq, ipu_irq_handler, 0, + "imx_drm", ipu_crtc); + if (ret < 0) { + dev_err(ipu_crtc->dev, "irq request failed with %d.\n", ret); + goto err_put_resources; + } + + disable_irq(ipu_crtc->irq); + return 0; err_put_resources: -- cgit v1.2.3 From b5ae11463a67a5e468dd67482ab2308994da9b2b Mon Sep 17 00:00:00 2001 From: Kumar Amit Mehta Date: Thu, 21 Feb 2013 22:07:08 -0800 Subject: staging: comedi: drivers: usbduxsigma.c: fix DMA buffers on stack This patch fixes an instance of DMA buffer on stack(being passed to usb_control_msg)for the USB-DUXsigma Board driver. Found using smatch. Signed-off-by: Kumar Amit Mehta Reviewed-by: Dan Carpenter Reviewed-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbduxsigma.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index d066351a71b2..a728c8fc32a2 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -681,7 +681,11 @@ static void usbduxsub_ao_IsocIrq(struct urb *urb) static int usbduxsub_start(struct usbduxsub *usbduxsub) { int errcode = 0; - uint8_t local_transfer_buffer[16]; + uint8_t *local_transfer_buffer; + + local_transfer_buffer = kmalloc(16, GFP_KERNEL); + if (!local_transfer_buffer) + return -ENOMEM; /* 7f92 to zero */ local_transfer_buffer[0] = 0; @@ -702,19 +706,22 @@ static int usbduxsub_start(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) { + if (errcode < 0) dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (start)\n"); - return errcode; - } - return 0; + + kfree(local_transfer_buffer); + return errcode; } static int usbduxsub_stop(struct usbduxsub *usbduxsub) { int errcode = 0; + uint8_t *local_transfer_buffer; - uint8_t local_transfer_buffer[16]; + local_transfer_buffer = kmalloc(16, GFP_KERNEL); + if (!local_transfer_buffer) + return -ENOMEM; /* 7f92 to one */ local_transfer_buffer[0] = 1; @@ -732,12 +739,12 @@ static int usbduxsub_stop(struct usbduxsub *usbduxsub) 1, /* Timeout */ BULK_TIMEOUT); - if (errcode < 0) { + if (errcode < 0) dev_err(&usbduxsub->interface->dev, "comedi_: control msg failed (stop)\n"); - return errcode; - } - return 0; + + kfree(local_transfer_buffer); + return errcode; } static int usbduxsub_upload(struct usbduxsub *usbduxsub, -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From aa1e1234826e21197f818ca0abf519775ad4eb5c Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 4 Mar 2013 20:42:00 +0100 Subject: staging/vt6656: Fix too large integer constant warning on 32-bit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/staging/vt6656/card.c: In function ‘CARDqGetNextTBTT’: drivers/staging/vt6656/card.c:793: warning: integer constant is too large for ‘unsigned long’ type Commit c7b7cad0d8df823ea063c86a54316bbcbfa04a7c ("staging/vt6656: Fix sparse warning constant 0xffffffff00000000U is so big it is unsigned long") changed the constant to "0xffffffff00000000UL", but that only works on 64-bit. Change it "0xffffffff00000000ULL" to fix it for 32-bit, too. Signed-off-by: Geert Uytterhoeven Reviewed-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 22918a106d73..d2479b766450 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -790,7 +790,7 @@ u64 CARDqGetNextTBTT(u64 qwTSF, WORD wBeaconInterval) if ((~uLowNextTBTT) < uLowRemain) qwTSF = ((qwTSF >> 32) + 1) << 32; - qwTSF = (qwTSF & 0xffffffff00000000UL) | + qwTSF = (qwTSF & 0xffffffff00000000ULL) | (u64)(uLowNextTBTT + uLowRemain); return (qwTSF); -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 564c526a1bed5e42b5cd52cfe1752c4296ef17a6 Mon Sep 17 00:00:00 2001 From: Ian Abbott Date: Tue, 5 Mar 2013 13:13:44 +0000 Subject: staging: comedi: dt9812: use CR_CHAN() for channel number As pointed out by Dan Carpenper in , the dt9812 comedi driver's use of the `chanspec` member of `struct comedi_insn` as a channel number is incorrect. Change it to use `CR_CHAN(insn->chanspec)` as the channel number (where `insn` is a pointer to the `struct comedi_insn` being processed). Reported-by: Dan Carpenter Cc: stable # 3.8 onwards Cc: Anders Blomdell Signed-off-by: Ian Abbott Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/dt9812.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/comedi/drivers/dt9812.c b/drivers/staging/comedi/drivers/dt9812.c index 192cf088f834..57b451904791 100644 --- a/drivers/staging/comedi/drivers/dt9812.c +++ b/drivers/staging/comedi/drivers/dt9812.c @@ -947,12 +947,13 @@ static int dt9812_di_rinsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); int n; u8 bits = 0; dt9812_digital_in(devpriv->slot, &bits); for (n = 0; n < insn->n; n++) - data[n] = ((1 << insn->chanspec) & bits) != 0; + data[n] = ((1 << channel) & bits) != 0; return n; } @@ -961,12 +962,13 @@ static int dt9812_do_winsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); int n; u8 bits = 0; dt9812_digital_out_shadow(devpriv->slot, &bits); for (n = 0; n < insn->n; n++) { - u8 mask = 1 << insn->chanspec; + u8 mask = 1 << channel; bits &= ~mask; if (data[n]) @@ -981,13 +983,13 @@ static int dt9812_ai_rinsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); int n; for (n = 0; n < insn->n; n++) { u16 value = 0; - dt9812_analog_in(devpriv->slot, insn->chanspec, &value, - DT9812_GAIN_1); + dt9812_analog_in(devpriv->slot, channel, &value, DT9812_GAIN_1); data[n] = value; } return n; @@ -998,12 +1000,13 @@ static int dt9812_ao_rinsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); int n; u16 value; for (n = 0; n < insn->n; n++) { value = 0; - dt9812_analog_out_shadow(devpriv->slot, insn->chanspec, &value); + dt9812_analog_out_shadow(devpriv->slot, channel, &value); data[n] = value; } return n; @@ -1014,10 +1017,11 @@ static int dt9812_ao_winsn(struct comedi_device *dev, unsigned int *data) { struct comedi_dt9812 *devpriv = dev->private; + unsigned int channel = CR_CHAN(insn->chanspec); int n; for (n = 0; n < insn->n; n++) - dt9812_analog_out(devpriv->slot, insn->chanspec, data[n]); + dt9812_analog_out(devpriv->slot, channel, data[n]); return n; } -- cgit v1.2.3 From d2e0bca377dc0f85acd19df465122f361a6c9e99 Mon Sep 17 00:00:00 2001 From: Liu Jinsong Date: Tue, 12 Mar 2013 06:42:16 +0800 Subject: xen/acpi: remove redundant acpi/acpi_drivers.h include It's redundant since linux/acpi.h has include it when CONFIG_ACPI enabled, and when CONFIG_ACPI disabled it will trigger compiling warning In file included from drivers/xen/xen-stub.c:28:0: include/acpi/acpi_drivers.h:103:31: warning: 'struct acpi_device' declared inside parameter list [enabled by default] include/acpi/acpi_drivers.h:103:31: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] include/acpi/acpi_drivers.h:107:43: warning: 'struct acpi_pci_root' declared inside parameter list [enabled by default] Reported-by: Wu Fengguang Signed-off-by: Liu Jinsong Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xen-stub.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/xen-stub.c b/drivers/xen/xen-stub.c index d85e411cbf89..bbef194c5b01 100644 --- a/drivers/xen/xen-stub.c +++ b/drivers/xen/xen-stub.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #ifdef CONFIG_ACPI -- cgit v1.2.3 From 0e367ae46503cfe7791460c8ba8434a5d60b2bd5 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Thu, 7 Mar 2013 17:32:01 +0000 Subject: xen/blkback: correctly respond to unknown, non-native requests If the frontend is using a non-native protocol (e.g., a 64-bit frontend with a 32-bit backend) and it sent an unrecognized request, the request was not translated and the response would have the incorrect ID. This may cause the frontend driver to behave incorrectly or crash. Since the ID field in the request is always in the same place, regardless of the request type we can get the correct ID and make a valid response (which will report BLKIF_RSP_EOPNOTSUPP). This bug affected 64-bit SLES 11 guests when using a 32-bit backend. This guest does a BLKIF_OP_RESERVED_1 (BLKIF_OP_PACKET in the SLES source) and would crash in blkif_int() as the ID in the response would be invalid. Signed-off-by: David Vrabel Cc: stable@vger.kernel.org Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 31 +++++++++++++++++++++++++++---- drivers/block/xen-blkback/common.h | 25 +++++++++++++++++++++++++ include/xen/interface/io/blkif.h | 10 ++++++++++ 3 files changed, 62 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 6d1cc3df2ac6..1a0faf6370ca 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -679,6 +679,16 @@ static int dispatch_discard_io(struct xen_blkif *blkif, return err; } +static int dispatch_other_io(struct xen_blkif *blkif, + struct blkif_request *req, + struct pending_req *pending_req) +{ + free_req(pending_req); + make_response(blkif, req->u.other.id, req->operation, + BLKIF_RSP_EOPNOTSUPP); + return -EIO; +} + static void xen_blk_drain_io(struct xen_blkif *blkif) { atomic_set(&blkif->drain, 1); @@ -800,17 +810,30 @@ __do_block_io_op(struct xen_blkif *blkif) /* Apply all sanity checks to /private copy/ of request. */ barrier(); - if (unlikely(req.operation == BLKIF_OP_DISCARD)) { + + switch (req.operation) { + case BLKIF_OP_READ: + case BLKIF_OP_WRITE: + case BLKIF_OP_WRITE_BARRIER: + case BLKIF_OP_FLUSH_DISKCACHE: + if (dispatch_rw_block_io(blkif, &req, pending_req)) + goto done; + break; + case BLKIF_OP_DISCARD: free_req(pending_req); if (dispatch_discard_io(blkif, &req)) - break; - } else if (dispatch_rw_block_io(blkif, &req, pending_req)) + goto done; + break; + default: + if (dispatch_other_io(blkif, &req, pending_req)) + goto done; break; + } /* Yield point for this unbounded loop. */ cond_resched(); } - +done: return more_to_do; } diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 6072390c7f57..195278ae993d 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -77,11 +77,18 @@ struct blkif_x86_32_request_discard { uint64_t nr_sectors; } __attribute__((__packed__)); +struct blkif_x86_32_request_other { + uint8_t _pad1; + blkif_vdev_t _pad2; + uint64_t id; /* private guest value, echoed in resp */ +} __attribute__((__packed__)); + struct blkif_x86_32_request { uint8_t operation; /* BLKIF_OP_??? */ union { struct blkif_x86_32_request_rw rw; struct blkif_x86_32_request_discard discard; + struct blkif_x86_32_request_other other; } u; } __attribute__((__packed__)); @@ -113,11 +120,19 @@ struct blkif_x86_64_request_discard { uint64_t nr_sectors; } __attribute__((__packed__)); +struct blkif_x86_64_request_other { + uint8_t _pad1; + blkif_vdev_t _pad2; + uint32_t _pad3; /* offsetof(blkif_..,u.discard.id)==8 */ + uint64_t id; /* private guest value, echoed in resp */ +} __attribute__((__packed__)); + struct blkif_x86_64_request { uint8_t operation; /* BLKIF_OP_??? */ union { struct blkif_x86_64_request_rw rw; struct blkif_x86_64_request_discard discard; + struct blkif_x86_64_request_other other; } u; } __attribute__((__packed__)); @@ -278,6 +293,11 @@ static inline void blkif_get_x86_32_req(struct blkif_request *dst, dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; default: + /* + * Don't know how to translate this op. Only get the + * ID so failure can be reported to the frontend. + */ + dst->u.other.id = src->u.other.id; break; } } @@ -309,6 +329,11 @@ static inline void blkif_get_x86_64_req(struct blkif_request *dst, dst->u.discard.nr_sectors = src->u.discard.nr_sectors; break; default: + /* + * Don't know how to translate this op. Only get the + * ID so failure can be reported to the frontend. + */ + dst->u.other.id = src->u.other.id; break; } } diff --git a/include/xen/interface/io/blkif.h b/include/xen/interface/io/blkif.h index 01c3d62436ef..ffd4652de91c 100644 --- a/include/xen/interface/io/blkif.h +++ b/include/xen/interface/io/blkif.h @@ -138,11 +138,21 @@ struct blkif_request_discard { uint8_t _pad3; } __attribute__((__packed__)); +struct blkif_request_other { + uint8_t _pad1; + blkif_vdev_t _pad2; /* only for read/write requests */ +#ifdef CONFIG_X86_64 + uint32_t _pad3; /* offsetof(blkif_req..,u.other.id)==8*/ +#endif + uint64_t id; /* private guest value, echoed in resp */ +} __attribute__((__packed__)); + struct blkif_request { uint8_t operation; /* BLKIF_OP_??? */ union { struct blkif_request_rw rw; struct blkif_request_discard discard; + struct blkif_request_other other; } u; } __attribute__((__packed__)); -- cgit v1.2.3 From 986cacbd26abe5d498be922cd6632f1ec376c271 Mon Sep 17 00:00:00 2001 From: Zoltan Kiss Date: Mon, 11 Mar 2013 16:15:50 +0000 Subject: xen/blkback: Change statistics counter types to unsigned These values shouldn't be negative, but after an overflow their value can turn into negative, if they are signed. xentop can show bogus values in this case. Signed-off-by: Zoltan Kiss Reported-by: Ichiro Ogino Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 4 ++-- drivers/block/xen-blkback/common.h | 14 +++++++------- drivers/block/xen-blkback/xenbus.c | 14 +++++++------- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 1a0faf6370ca..eaccc222a1dc 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -381,8 +381,8 @@ irqreturn_t xen_blkif_be_int(int irq, void *dev_id) static void print_stats(struct xen_blkif *blkif) { - pr_info("xen-blkback (%s): oo %3d | rd %4d | wr %4d | f %4d" - " | ds %4d\n", + pr_info("xen-blkback (%s): oo %3llu | rd %4llu | wr %4llu | f %4llu" + " | ds %4llu\n", current->comm, blkif->st_oo_req, blkif->st_rd_req, blkif->st_wr_req, blkif->st_f_req, blkif->st_ds_req); diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index 195278ae993d..da78346487ae 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -223,13 +223,13 @@ struct xen_blkif { /* statistics */ unsigned long st_print; - int st_rd_req; - int st_wr_req; - int st_oo_req; - int st_f_req; - int st_ds_req; - int st_rd_sect; - int st_wr_sect; + unsigned long long st_rd_req; + unsigned long long st_wr_req; + unsigned long long st_oo_req; + unsigned long long st_f_req; + unsigned long long st_ds_req; + unsigned long long st_rd_sect; + unsigned long long st_wr_sect; wait_queue_head_t waiting_to_free; }; diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index 5e237f630c47..8bfd1bcf95ec 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -230,13 +230,13 @@ int __init xen_blkif_interface_init(void) } \ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) -VBD_SHOW(oo_req, "%d\n", be->blkif->st_oo_req); -VBD_SHOW(rd_req, "%d\n", be->blkif->st_rd_req); -VBD_SHOW(wr_req, "%d\n", be->blkif->st_wr_req); -VBD_SHOW(f_req, "%d\n", be->blkif->st_f_req); -VBD_SHOW(ds_req, "%d\n", be->blkif->st_ds_req); -VBD_SHOW(rd_sect, "%d\n", be->blkif->st_rd_sect); -VBD_SHOW(wr_sect, "%d\n", be->blkif->st_wr_sect); +VBD_SHOW(oo_req, "%llu\n", be->blkif->st_oo_req); +VBD_SHOW(rd_req, "%llu\n", be->blkif->st_rd_req); +VBD_SHOW(wr_req, "%llu\n", be->blkif->st_wr_req); +VBD_SHOW(f_req, "%llu\n", be->blkif->st_f_req); +VBD_SHOW(ds_req, "%llu\n", be->blkif->st_ds_req); +VBD_SHOW(rd_sect, "%llu\n", be->blkif->st_rd_sect); +VBD_SHOW(wr_sect, "%llu\n", be->blkif->st_wr_sect); static struct attribute *xen_vbdstat_attrs[] = { &dev_attr_oo_req.attr, -- cgit v1.2.3 From fd5014ad5c80a75713b13a95eb717cc697dda5d5 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 11 Mar 2013 20:01:08 +0200 Subject: usb: musb: core: fix possible build error with randconfig when making commit e574d57 (usb: musb: fix compile warning) I forgot to git add this part of the patch which ended up introducing a possible build error. Signed-off-by: Felipe Balbi Signed-off-by: Greg Kroah-Hartman --- drivers/usb/musb/musb_core.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index 13382e053d59..daec6e0f7e38 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c @@ -1624,8 +1624,6 @@ EXPORT_SYMBOL_GPL(musb_dma_completion); /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_SYSFS - static ssize_t musb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1742,8 +1740,6 @@ static const struct attribute_group musb_attr_group = { .attrs = musb_attributes, }; -#endif /* sysfs */ - /* Only used to provide driver mode change events */ static void musb_irq_work(struct work_struct *data) { -- cgit v1.2.3 From 2d90e63603ac235aecd7d20e234616e0682c8b1f Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 19 Feb 2013 09:47:09 -0600 Subject: qcaux: add Franklin U600 4 ports; AT/PPP is standard CDC-ACM. The other three (added by this patch) are QCDM/DIAG, possibly GPS, and unknown. Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcaux.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/qcaux.c b/drivers/usb/serial/qcaux.c index 9b1b96f2d095..31f81c3c15eb 100644 --- a/drivers/usb/serial/qcaux.c +++ b/drivers/usb/serial/qcaux.c @@ -69,6 +69,7 @@ static struct usb_device_id id_table[] = { { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfd, 0xff) }, /* NMEA */ { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xfe, 0xff) }, /* WMC */ { USB_VENDOR_AND_INTERFACE_INFO(UTSTARCOM_VENDOR_ID, 0xff, 0xff, 0xff) }, /* DIAG */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1fac, 0x0151, 0xff, 0xff, 0xff) }, { }, }; MODULE_DEVICE_TABLE(usb, id_table); -- cgit v1.2.3 From f37912039eb04979f269de0a7dc1a601702df51a Mon Sep 17 00:00:00 2001 From: Philip J Kelleher Date: Mon, 25 Feb 2013 12:27:46 -0600 Subject: block: IBM RamSan 70/80 trivial changes. This patch includes trivial changes that were recommended by different members of the Linux Community. Changes include: o Removing the redundant wmb(). o Formatting o Various other little things. Signed-off-by: Philip J Kelleher Signed-off-by: Jens Axboe --- drivers/block/rsxx/config.c | 6 ++---- drivers/block/rsxx/core.c | 4 ++-- drivers/block/rsxx/cregs.c | 13 +++---------- drivers/block/rsxx/dma.c | 12 ------------ drivers/block/rsxx/rsxx.h | 6 ++++-- 5 files changed, 11 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rsxx/config.c b/drivers/block/rsxx/config.c index a295e7e9ee41..0d8cb18284eb 100644 --- a/drivers/block/rsxx/config.c +++ b/drivers/block/rsxx/config.c @@ -29,10 +29,8 @@ #include "rsxx_priv.h" #include "rsxx_cfg.h" -static void initialize_config(void *config) +static void initialize_config(struct rsxx_card_cfg *cfg) { - struct rsxx_card_cfg *cfg = config; - cfg->hdr.version = RSXX_CFG_VERSION; cfg->data.block_size = RSXX_HW_BLK_SIZE; @@ -181,7 +179,7 @@ int rsxx_load_config(struct rsxx_cardinfo *card) } else { dev_info(CARD_TO_DEV(card), "Initializing card configuration.\n"); - initialize_config(card); + initialize_config(&card->config); st = rsxx_save_config(card); if (st) return st; diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index e5162487686a..edbae10e7f6f 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -161,9 +161,9 @@ static irqreturn_t rsxx_isr(int irq, void *pdata) } /*----------------- Card Event Handler -------------------*/ -static char *rsxx_card_state_to_str(unsigned int state) +static const char * const rsxx_card_state_to_str(unsigned int state) { - static char *state_strings[] = { + static const char * const state_strings[] = { "Unknown", "Shutdown", "Starting", "Formatting", "Uninitialized", "Good", "Shutting Down", "Fault", "Read Only Fault", "dStroying" diff --git a/drivers/block/rsxx/cregs.c b/drivers/block/rsxx/cregs.c index 80bbe639fccd..224156435261 100644 --- a/drivers/block/rsxx/cregs.c +++ b/drivers/block/rsxx/cregs.c @@ -126,13 +126,6 @@ static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) cmd->buf, cmd->stream); } - /* - * Data copy must complete before initiating the command. This is - * needed for weakly ordered processors (i.e. PowerPC), so that all - * neccessary registers are written before we kick the hardware. - */ - wmb(); - /* Setting the valid bit will kick off the command. */ iowrite32(cmd->op, card->regmap + CREG_CMD); } @@ -399,12 +392,12 @@ static int __issue_creg_rw(struct rsxx_cardinfo *card, return st; /* - * This timeout is neccessary for unresponsive hardware. The additional + * This timeout is necessary for unresponsive hardware. The additional * 20 seconds to used to guarantee that each cregs requests has time to * complete. */ - timeout = msecs_to_jiffies((CREG_TIMEOUT_MSEC * - card->creg_ctrl.q_depth) + 20000); + timeout = msecs_to_jiffies(CREG_TIMEOUT_MSEC * + card->creg_ctrl.q_depth + 20000); /* * The creg interface is guaranteed to complete. It has a timeout diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c index 63176e67662f..7c3a57bed2cd 100644 --- a/drivers/block/rsxx/dma.c +++ b/drivers/block/rsxx/dma.c @@ -432,16 +432,6 @@ static void rsxx_issue_dmas(struct work_struct *work) /* Let HW know we've queued commands. */ if (cmds_pending) { - /* - * We must guarantee that the CPU writes to 'ctrl->cmd.buf' - * (which is in PCI-consistent system-memory) from the loop - * above make it into the coherency domain before the - * following PIO "trigger" updating the cmd.idx. A WMB is - * sufficient. We need not explicitly CPU cache-flush since - * the memory is a PCI-consistent (ie; coherent) mapping. - */ - wmb(); - atomic_add(cmds_pending, &ctrl->stats.hw_q_depth); mod_timer(&ctrl->activity_timer, jiffies + DMA_ACTIVITY_TIMEOUT); @@ -798,8 +788,6 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev, iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); - wmb(); - return 0; } diff --git a/drivers/block/rsxx/rsxx.h b/drivers/block/rsxx/rsxx.h index 2e50b65902b7..24ba3642bd89 100644 --- a/drivers/block/rsxx/rsxx.h +++ b/drivers/block/rsxx/rsxx.h @@ -27,15 +27,17 @@ /*----------------- IOCTL Definitions -------------------*/ +#define RSXX_MAX_DATA 8 + struct rsxx_reg_access { __u32 addr; __u32 cnt; __u32 stat; __u32 stream; - __u32 data[8]; + __u32 data[RSXX_MAX_DATA]; }; -#define RSXX_MAX_REG_CNT (8 * (sizeof(__u32))) +#define RSXX_MAX_REG_CNT (RSXX_MAX_DATA * (sizeof(__u32))) #define RSXX_IOC_MAGIC 'r' -- cgit v1.2.3 From 03ac03a8971bd7e9f8c8b20a309b61beaf154d60 Mon Sep 17 00:00:00 2001 From: Philip J Kelleher Date: Mon, 25 Feb 2013 12:31:31 -0600 Subject: block: IBM RamSan 70/80 fixes inconsistent locking. This patch includes changes to the cregs locking scheme. Before, inconsistant locking would occur because of misuse of spin_lock, spin_lock_bh, and counter parts. Signed-off-by: Philip J Kelleher Signed-off-by: Jens Axboe --- drivers/block/rsxx/cregs.c | 44 ++++++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rsxx/cregs.c b/drivers/block/rsxx/cregs.c index 224156435261..0539a25877eb 100644 --- a/drivers/block/rsxx/cregs.c +++ b/drivers/block/rsxx/cregs.c @@ -99,22 +99,6 @@ static void copy_from_creg_data(struct rsxx_cardinfo *card, } } -static struct creg_cmd *pop_active_cmd(struct rsxx_cardinfo *card) -{ - struct creg_cmd *cmd; - - /* - * Spin lock is needed because this can be called in atomic/interrupt - * context. - */ - spin_lock_bh(&card->creg_ctrl.lock); - cmd = card->creg_ctrl.active_cmd; - card->creg_ctrl.active_cmd = NULL; - spin_unlock_bh(&card->creg_ctrl.lock); - - return cmd; -} - static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) { iowrite32(cmd->addr, card->regmap + CREG_ADD); @@ -189,11 +173,11 @@ static int creg_queue_cmd(struct rsxx_cardinfo *card, cmd->cb_private = cb_private; cmd->status = 0; - spin_lock(&card->creg_ctrl.lock); + spin_lock_bh(&card->creg_ctrl.lock); list_add_tail(&cmd->list, &card->creg_ctrl.queue); card->creg_ctrl.q_depth++; creg_kick_queue(card); - spin_unlock(&card->creg_ctrl.lock); + spin_unlock_bh(&card->creg_ctrl.lock); return 0; } @@ -203,7 +187,11 @@ static void creg_cmd_timed_out(unsigned long data) struct rsxx_cardinfo *card = (struct rsxx_cardinfo *) data; struct creg_cmd *cmd; - cmd = pop_active_cmd(card); + spin_lock(&card->creg_ctrl.lock); + cmd = card->creg_ctrl.active_cmd; + card->creg_ctrl.active_cmd = NULL; + spin_unlock(&card->creg_ctrl.lock); + if (cmd == NULL) { card->creg_ctrl.creg_stats.creg_timeout++; dev_warn(CARD_TO_DEV(card), @@ -240,7 +228,11 @@ static void creg_cmd_done(struct work_struct *work) if (del_timer_sync(&card->creg_ctrl.cmd_timer) == 0) card->creg_ctrl.creg_stats.failed_cancel_timer++; - cmd = pop_active_cmd(card); + spin_lock_bh(&card->creg_ctrl.lock); + cmd = card->creg_ctrl.active_cmd; + card->creg_ctrl.active_cmd = NULL; + spin_unlock_bh(&card->creg_ctrl.lock); + if (cmd == NULL) { dev_err(CARD_TO_DEV(card), "Spurious creg interrupt!\n"); @@ -289,10 +281,10 @@ creg_done: kmem_cache_free(creg_cmd_pool, cmd); - spin_lock(&card->creg_ctrl.lock); + spin_lock_bh(&card->creg_ctrl.lock); card->creg_ctrl.active = 0; creg_kick_queue(card); - spin_unlock(&card->creg_ctrl.lock); + spin_unlock_bh(&card->creg_ctrl.lock); } static void creg_reset(struct rsxx_cardinfo *card) @@ -317,7 +309,7 @@ static void creg_reset(struct rsxx_cardinfo *card) "Resetting creg interface for recovery\n"); /* Cancel outstanding commands */ - spin_lock(&card->creg_ctrl.lock); + spin_lock_bh(&card->creg_ctrl.lock); list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) { list_del(&cmd->list); card->creg_ctrl.q_depth--; @@ -338,7 +330,7 @@ static void creg_reset(struct rsxx_cardinfo *card) card->creg_ctrl.active = 0; } - spin_unlock(&card->creg_ctrl.lock); + spin_unlock_bh(&card->creg_ctrl.lock); card->creg_ctrl.reset = 0; spin_lock_irqsave(&card->irq_lock, flags); @@ -705,7 +697,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card) int cnt = 0; /* Cancel outstanding commands */ - spin_lock(&card->creg_ctrl.lock); + spin_lock_bh(&card->creg_ctrl.lock); list_for_each_entry_safe(cmd, tmp, &card->creg_ctrl.queue, list) { list_del(&cmd->list); if (cmd->cb) @@ -730,7 +722,7 @@ void rsxx_creg_destroy(struct rsxx_cardinfo *card) "Canceled active creg command\n"); kmem_cache_free(creg_cmd_pool, cmd); } - spin_unlock(&card->creg_ctrl.lock); + spin_unlock_bh(&card->creg_ctrl.lock); cancel_work_sync(&card->creg_ctrl.done_work); } -- cgit v1.2.3 From 9bb3c4469e317919b0fde8c0e0a3ebe7bd2cf167 Mon Sep 17 00:00:00 2001 From: Philip J Kelleher Date: Wed, 27 Feb 2013 09:24:59 -0600 Subject: block: IBM RamSan 70/80 branding changes. This patch includes changing the hardware branding name from IBM RamSan to IBM FlashSystem. v2 Changes include: o Removing the unnecessary IBM Vendor ID #define v1 Changes include: o Changed all references of RamSan to FlashSystem. o Changed the vendor/device IDs for the product. o Changed driver version number. o Updated the MAINTAINERS file. o Various other little things. Signed-off-by: Philip J Kelleher Signed-off-by: Jens Axboe --- MAINTAINERS | 12 ++++++------ drivers/block/Kconfig | 4 ++-- drivers/block/rsxx/Makefile | 2 +- drivers/block/rsxx/config.c | 2 +- drivers/block/rsxx/core.c | 10 ++++------ drivers/block/rsxx/dma.c | 2 +- drivers/block/rsxx/rsxx_cfg.h | 2 +- drivers/block/rsxx/rsxx_priv.h | 9 +++------ 8 files changed, 19 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 95616582c728..a00f0eaf0eda 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3242,6 +3242,12 @@ F: Documentation/firmware_class/ F: drivers/base/firmware*.c F: include/linux/firmware.h +FLASHSYSTEM DRIVER (IBM FlashSystem 70/80 PCI SSD Flash Card) +M: Joshua Morris +M: Philip Kelleher +S: Maintained +F: drivers/block/rsxx/ + FLOPPY DRIVER M: Jiri Kosina T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git @@ -6516,12 +6522,6 @@ S: Maintained F: Documentation/blockdev/ramdisk.txt F: drivers/block/brd.c -RAMSAM DRIVER (IBM RamSan 70/80 PCI SSD Flash Card) -M: Joshua Morris -M: Philip Kelleher -S: Maintained -F: drivers/block/rsxx/ - RANDOM NUMBER DRIVER M: Theodore Ts'o" S: Maintained diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 5dc0daed8fac..b81ddfea1da0 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -532,11 +532,11 @@ config BLK_DEV_RBD If unsure, say N. config BLK_DEV_RSXX - tristate "RamSam PCIe Flash SSD Device Driver" + tristate "IBM FlashSystem 70/80 PCIe SSD Device Driver" depends on PCI help Device driver for IBM's high speed PCIe SSD - storage devices: RamSan-70 and RamSan-80. + storage devices: FlashSystem-70 and FlashSystem-80. To compile this driver as a module, choose M here: the module will be called rsxx. diff --git a/drivers/block/rsxx/Makefile b/drivers/block/rsxx/Makefile index f35cd0b71f7b..b1c53c0aa450 100644 --- a/drivers/block/rsxx/Makefile +++ b/drivers/block/rsxx/Makefile @@ -1,2 +1,2 @@ obj-$(CONFIG_BLK_DEV_RSXX) += rsxx.o -rsxx-y := config.o core.o cregs.o dev.o dma.o +rsxx-objs := config.o core.o cregs.o dev.o dma.o diff --git a/drivers/block/rsxx/config.c b/drivers/block/rsxx/config.c index 0d8cb18284eb..10cd530d3e10 100644 --- a/drivers/block/rsxx/config.c +++ b/drivers/block/rsxx/config.c @@ -35,7 +35,7 @@ static void initialize_config(struct rsxx_card_cfg *cfg) cfg->data.block_size = RSXX_HW_BLK_SIZE; cfg->data.stripe_size = RSXX_HW_BLK_SIZE; - cfg->data.vendor_id = RSXX_VENDOR_ID_TMS_IBM; + cfg->data.vendor_id = RSXX_VENDOR_ID_IBM; cfg->data.cache_order = (-1); cfg->data.intr_coal.mode = RSXX_INTR_COAL_DISABLED; cfg->data.intr_coal.count = 0; diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index edbae10e7f6f..b82ee7baf0e8 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -39,8 +39,8 @@ #define NO_LEGACY 0 -MODULE_DESCRIPTION("IBM RamSan PCIe Flash SSD Device Driver"); -MODULE_AUTHOR("IBM "); +MODULE_DESCRIPTION("IBM FlashSystem 70/80 PCIe SSD Device Driver"); +MODULE_AUTHOR("Joshua Morris/Philip Kelleher, IBM"); MODULE_LICENSE("GPL"); MODULE_VERSION(DRIVER_VERSION); @@ -593,10 +593,8 @@ static void rsxx_pci_shutdown(struct pci_dev *dev) } static DEFINE_PCI_DEVICE_TABLE(rsxx_pci_ids) = { - {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS70_FLASH)}, - {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS70D_FLASH)}, - {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS80_FLASH)}, - {PCI_DEVICE(PCI_VENDOR_ID_TMS_IBM, PCI_DEVICE_ID_RS81_FLASH)}, + {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS70_FLASH)}, + {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS80_FLASH)}, {0,}, }; diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c index 7c3a57bed2cd..efd75b55a670 100644 --- a/drivers/block/rsxx/dma.c +++ b/drivers/block/rsxx/dma.c @@ -28,7 +28,7 @@ struct rsxx_dma { struct list_head list; u8 cmd; - unsigned int laddr; /* Logical address on the ramsan */ + unsigned int laddr; /* Logical address */ struct { u32 off; u32 cnt; diff --git a/drivers/block/rsxx/rsxx_cfg.h b/drivers/block/rsxx/rsxx_cfg.h index c025fe5fdb70..f384c943846d 100644 --- a/drivers/block/rsxx/rsxx_cfg.h +++ b/drivers/block/rsxx/rsxx_cfg.h @@ -58,7 +58,7 @@ struct rsxx_card_cfg { }; /* Vendor ID Values */ -#define RSXX_VENDOR_ID_TMS_IBM 0 +#define RSXX_VENDOR_ID_IBM 0 #define RSXX_VENDOR_ID_DSI 1 #define RSXX_VENDOR_COUNT 2 diff --git a/drivers/block/rsxx/rsxx_priv.h b/drivers/block/rsxx/rsxx_priv.h index a1ac907d8f4c..f5a95f75bd57 100644 --- a/drivers/block/rsxx/rsxx_priv.h +++ b/drivers/block/rsxx/rsxx_priv.h @@ -45,16 +45,13 @@ struct proc_cmd; -#define PCI_VENDOR_ID_TMS_IBM 0x15B6 -#define PCI_DEVICE_ID_RS70_FLASH 0x0019 -#define PCI_DEVICE_ID_RS70D_FLASH 0x001A -#define PCI_DEVICE_ID_RS80_FLASH 0x001C -#define PCI_DEVICE_ID_RS81_FLASH 0x001E +#define PCI_DEVICE_ID_FS70_FLASH 0x04A9 +#define PCI_DEVICE_ID_FS80_FLASH 0x04AA #define RS70_PCI_REV_SUPPORTED 4 #define DRIVER_NAME "rsxx" -#define DRIVER_VERSION "3.7" +#define DRIVER_VERSION "4.0" /* Block size is 4096 */ #define RSXX_HW_BLK_SHIFT 12 -- cgit v1.2.3 From 1ebfd109822ea35b71aee4efe9ddc2e1b9ac0ed7 Mon Sep 17 00:00:00 2001 From: Philip J Kelleher Date: Mon, 25 Feb 2013 13:09:40 -0600 Subject: block: IBM RamSan 70/80 error message bug fix. This patch includes a simple change to the rsxx_pci_remove function that caused error messages because traffic was halted too early. Signed-off-by: Philip J Kelleher Signed-off-by: Jens Axboe --- drivers/block/rsxx/core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index b82ee7baf0e8..cbbdff113f46 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -538,9 +538,6 @@ static void rsxx_pci_remove(struct pci_dev *dev) rsxx_disable_ier_and_isr(card, CR_INTR_EVENT); spin_unlock_irqrestore(&card->irq_lock, flags); - /* Prevent work_structs from re-queuing themselves. */ - card->halt = 1; - cancel_work_sync(&card->event_work); rsxx_destroy_dev(card); @@ -549,6 +546,10 @@ static void rsxx_pci_remove(struct pci_dev *dev) spin_lock_irqsave(&card->irq_lock, flags); rsxx_disable_ier_and_isr(card, CR_INTR_ALL); spin_unlock_irqrestore(&card->irq_lock, flags); + + /* Prevent work_structs from re-queuing themselves. */ + card->halt = 1; + free_irq(dev->irq, card); if (!force_legacy) -- cgit v1.2.3 From 94a32d10f47b637ae24b78b1ddc7ef0e8396fda4 Mon Sep 17 00:00:00 2001 From: Sunguk Lee Date: Tue, 12 Mar 2013 04:41:58 +0900 Subject: Bluetooth: Device 0cf3:3008 should map AR 3012 T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=3008 Rev= 0.01 S: Manufacturer=Atheros Communications S: Product=Bluetooth USB Host Controller S: SerialNumber=Alaska Day 2006 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Signed-off-by: Sunguk Lee Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index b9908dd84529..3095d2e74f24 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -74,6 +74,7 @@ static struct usb_device_id ath3k_table[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0CF3, 0x3004) }, + { USB_DEVICE(0x0CF3, 0x3008) }, { USB_DEVICE(0x0CF3, 0x311D) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x04CA, 0x3004) }, @@ -107,6 +108,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 59cde8e882ff..e547851870e7 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -132,6 +132,7 @@ static struct usb_device_id blacklist_table[] = { /* Atheros 3012 with sflash firmware */ { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 26bacba15ea849b61ae58d30a560b1f28a16d3a2 Mon Sep 17 00:00:00 2001 From: Roger Quadros Date: Wed, 27 Feb 2013 15:19:24 +0200 Subject: mfd: omap-usb-host: Actually update hostconfig The helper functions omap_usbhs_rev1_hostconfig() and omap_usbhs_rev2_hostconfig() don't write into the hostconfig register. Make sure that we write the return value into the hostconfig register. Signed-off-by: Roger Quadros Signed-off-by: Samuel Ortiz --- drivers/mfd/omap-usb-host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 6b5edf64de2b..4febc5c7fdee 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c @@ -460,15 +460,15 @@ static void omap_usbhs_init(struct device *dev) switch (omap->usbhs_rev) { case OMAP_USBHS_REV1: - omap_usbhs_rev1_hostconfig(omap, reg); + reg = omap_usbhs_rev1_hostconfig(omap, reg); break; case OMAP_USBHS_REV2: - omap_usbhs_rev2_hostconfig(omap, reg); + reg = omap_usbhs_rev2_hostconfig(omap, reg); break; default: /* newer revisions */ - omap_usbhs_rev2_hostconfig(omap, reg); + reg = omap_usbhs_rev2_hostconfig(omap, reg); break; } -- cgit v1.2.3 From 5c854aaecea0cd7da95ce2170ff305f8273d552d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 19 Feb 2013 23:20:33 +0800 Subject: mfd: Make AB8500_CORE select POWER_SUPPLY to fix build error This patch fixes below build error when CONFIG_POWER_SUPPLY is not set. drivers/built-in.o: In function `ab8500_power_off': drivers/mfd/ab8500-sysctrl.c:37: undefined reference to `power_supply_get_by_name' drivers/mfd/ab8500-sysctrl.c:53: undefined reference to `power_supply_get_by_name' make: *** [vmlinux] Error 1 Signed-off-by: Axel Lin Acked-by: Lee Jones Signed-off-by: Samuel Ortiz --- drivers/mfd/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 671f5b171c73..c346941a2515 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -858,6 +858,7 @@ config EZX_PCAP config AB8500_CORE bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU + select POWER_SUPPLY select MFD_CORE select IRQ_DOMAIN help -- cgit v1.2.3 From df545d1cd01aab3ba3f687d5423e6c3687b069d8 Mon Sep 17 00:00:00 2001 From: Laxman Dewangan Date: Fri, 1 Mar 2013 20:13:46 +0530 Subject: mfd: palmas: Provide irq flags through DT/platform data Currently driver sets the irq type to IRQF_TRIGGER_LOW which is causing interrupt registration failure in ARM based SoCs as: [ 0.208479] genirq: Setting trigger mode 8 for irq 118 failed (gic_set_type+0x0/0xf0) [ 0.208513] dummy 0-0059: Failed to request IRQ 118: -22 Provide the irq flags through platform data if device is registered through board file or get the irq type from DT node property in place of hardcoding the irq flag in driver to support multiple platforms. Also configure the device to generate the interrupt signal according to flag type. Signed-off-by: Laxman Dewangan Signed-off-by: Samuel Ortiz --- drivers/mfd/palmas.c | 36 +++++++++++++++++++++++++++++++++--- include/linux/mfd/palmas.h | 1 + 2 files changed, 34 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c index bbdbc50a3cca..73bf76df1044 100644 --- a/drivers/mfd/palmas.c +++ b/drivers/mfd/palmas.c @@ -257,9 +257,24 @@ static struct regmap_irq_chip palmas_irq_chip = { PALMAS_INT1_MASK), }; -static void palmas_dt_to_pdata(struct device_node *node, +static int palmas_set_pdata_irq_flag(struct i2c_client *i2c, struct palmas_platform_data *pdata) { + struct irq_data *irq_data = irq_get_irq_data(i2c->irq); + if (!irq_data) { + dev_err(&i2c->dev, "Invalid IRQ: %d\n", i2c->irq); + return -EINVAL; + } + + pdata->irq_flags = irqd_get_trigger_type(irq_data); + dev_info(&i2c->dev, "Irq flag is 0x%08x\n", pdata->irq_flags); + return 0; +} + +static void palmas_dt_to_pdata(struct i2c_client *i2c, + struct palmas_platform_data *pdata) +{ + struct device_node *node = i2c->dev.of_node; int ret; u32 prop; @@ -283,6 +298,8 @@ static void palmas_dt_to_pdata(struct device_node *node, pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK | PALMAS_POWER_CTRL_ENABLE1_MASK | PALMAS_POWER_CTRL_ENABLE2_MASK; + if (i2c->irq) + palmas_set_pdata_irq_flag(i2c, pdata); } static int palmas_i2c_probe(struct i2c_client *i2c, @@ -304,7 +321,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, if (!pdata) return -ENOMEM; - palmas_dt_to_pdata(node, pdata); + palmas_dt_to_pdata(i2c, pdata); } if (!pdata) @@ -344,6 +361,19 @@ static int palmas_i2c_probe(struct i2c_client *i2c, } } + /* Change interrupt line output polarity */ + if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH) + reg = PALMAS_POLARITY_CTRL_INT_POLARITY; + else + reg = 0; + ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE, + PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY, + reg); + if (ret < 0) { + dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret); + goto err; + } + /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); @@ -352,7 +382,7 @@ static int palmas_i2c_probe(struct i2c_client *i2c, regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, - IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip, + IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) goto err; diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h index a4d13d7cd001..3bbda22721ea 100644 --- a/include/linux/mfd/palmas.h +++ b/include/linux/mfd/palmas.h @@ -221,6 +221,7 @@ struct palmas_clk_platform_data { }; struct palmas_platform_data { + int irq_flags; int gpio_base; /* bit value to be loaded to the POWER_CTRL register */ -- cgit v1.2.3 From 80e4e6716e43500c5c7d4ff4f73fc1b56f024083 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Mar 2013 15:25:50 +0800 Subject: mfd: tps65912: Declare and use tps65912_irq_exit() Clean up interrupts on exit, silencing a sparse warning caused by tps65912_irq_exit() being defined but not prototyped as we go. Signed-off-by: Mark Brown Signed-off-by: Samuel Ortiz --- drivers/mfd/tps65912-core.c | 1 + include/linux/mfd/tps65912.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/tps65912-core.c b/drivers/mfd/tps65912-core.c index 4658b5bdcd84..aeb8e40ab424 100644 --- a/drivers/mfd/tps65912-core.c +++ b/drivers/mfd/tps65912-core.c @@ -169,6 +169,7 @@ err: void tps65912_device_exit(struct tps65912 *tps65912) { mfd_remove_devices(tps65912->dev); + tps65912_irq_exit(tps65912); kfree(tps65912); } diff --git a/include/linux/mfd/tps65912.h b/include/linux/mfd/tps65912.h index aaceab402ec5..6d309032dc0d 100644 --- a/include/linux/mfd/tps65912.h +++ b/include/linux/mfd/tps65912.h @@ -323,5 +323,6 @@ int tps65912_device_init(struct tps65912 *tps65912); void tps65912_device_exit(struct tps65912 *tps65912); int tps65912_irq_init(struct tps65912 *tps65912, int irq, struct tps65912_platform_data *pdata); +int tps65912_irq_exit(struct tps65912 *tps65912); #endif /* __LINUX_MFD_TPS65912_H */ -- cgit v1.2.3 From 6049bcefada077c5d3aec59f093701df711ad235 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 2 Mar 2013 15:30:35 +0800 Subject: mfd: twl4030-audio: Fix argument type for twl4030_audio_disable_resource() Looks like the conversion to enum was missed for the definition of this function, the declaration has been updated. Signed-off-by: Mark Brown Acked-by: Peter Ujfalusi Signed-off-by: Samuel Ortiz --- drivers/mfd/twl4030-audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c index e16edca92670..d2ab222138c2 100644 --- a/drivers/mfd/twl4030-audio.c +++ b/drivers/mfd/twl4030-audio.c @@ -118,7 +118,7 @@ EXPORT_SYMBOL_GPL(twl4030_audio_enable_resource); * Disable the resource. * The function returns with error or the content of the register */ -int twl4030_audio_disable_resource(unsigned id) +int twl4030_audio_disable_resource(enum twl4030_audio_res id) { struct twl4030_audio *audio = platform_get_drvdata(twl4030_audio_dev); int val; -- cgit v1.2.3 From 54fc4037ac449acf96ab88c3e65633c997df8a84 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sat, 9 Mar 2013 17:46:45 +0800 Subject: mfd: ab8500-gpadc: Complain if we fail to enable vtvout LDO Since commit c8801a8e "regulator: core: Mark all get and enable calls as __must_check", we must check return value of regulator_enable() to silence below build warning. CC drivers/mfd/ab8500-gpadc.o drivers/mfd/ab8500-gpadc.c: In function 'ab8500_gpadc_runtime_resume': drivers/mfd/ab8500-gpadc.c:598:18: warning: ignoring return value of 'regulator_enable', declared with attribute warn_unused_result [-Wunused-result] drivers/mfd/ab8500-gpadc.c: In function 'ab8500_gpadc_probe': drivers/mfd/ab8500-gpadc.c:655:18: warning: ignoring return value of 'regulator_enable', declared with attribute warn_unused_result [-Wunused-result] Also convert to devm_regulator_get(), this fixes a missing regulator_put() call in ab8500_gpadc_remove(). Signed-off-by: Axel Lin Signed-off-by: Samuel Ortiz --- drivers/mfd/ab8500-gpadc.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c index b1f3561b023f..5f341a50ee5a 100644 --- a/drivers/mfd/ab8500-gpadc.c +++ b/drivers/mfd/ab8500-gpadc.c @@ -594,9 +594,12 @@ static int ab8500_gpadc_runtime_suspend(struct device *dev) static int ab8500_gpadc_runtime_resume(struct device *dev) { struct ab8500_gpadc *gpadc = dev_get_drvdata(dev); + int ret; - regulator_enable(gpadc->regu); - return 0; + ret = regulator_enable(gpadc->regu); + if (ret) + dev_err(dev, "Failed to enable vtvout LDO: %d\n", ret); + return ret; } static int ab8500_gpadc_runtime_idle(struct device *dev) @@ -643,7 +646,7 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) } /* VTVout LDO used to power up ab8500-GPADC */ - gpadc->regu = regulator_get(&pdev->dev, "vddadc"); + gpadc->regu = devm_regulator_get(&pdev->dev, "vddadc"); if (IS_ERR(gpadc->regu)) { ret = PTR_ERR(gpadc->regu); dev_err(gpadc->dev, "failed to get vtvout LDO\n"); @@ -652,7 +655,11 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, gpadc); - regulator_enable(gpadc->regu); + ret = regulator_enable(gpadc->regu); + if (ret) { + dev_err(gpadc->dev, "Failed to enable vtvout LDO: %d\n", ret); + goto fail_enable; + } pm_runtime_set_autosuspend_delay(gpadc->dev, GPADC_AUDOSUSPEND_DELAY); pm_runtime_use_autosuspend(gpadc->dev); @@ -663,6 +670,8 @@ static int ab8500_gpadc_probe(struct platform_device *pdev) list_add_tail(&gpadc->node, &ab8500_gpadc_list); dev_dbg(gpadc->dev, "probe success\n"); return 0; + +fail_enable: fail_irq: free_irq(gpadc->irq, gpadc); fail: -- cgit v1.2.3 From 47ce9c4821fa41ef72c1004e1a362d08334cd717 Mon Sep 17 00:00:00 2001 From: Santosh Rastapur Date: Fri, 8 Mar 2013 03:35:29 +0000 Subject: cxgb4: Allow for backward compatibility with new VPD scheme. New scheme calls for 3rd party VPD at offset 0x0 and Chelsio VPD at offset 0x400 of the function. If no 3rd party VPD is present, then a copy of Chelsio's VPD will be at offset 0x0 to keep in line with PCI spec which requires the VPD to be present at offset 0x0. Signed-off-by: Santosh Rastapur Signed-off-by: Vipul Pandya Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index 4ce62031f62f..8049268ce0f2 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -497,8 +497,9 @@ int t4_memory_write(struct adapter *adap, int mtype, u32 addr, u32 len, } #define EEPROM_STAT_ADDR 0x7bfc -#define VPD_BASE 0 #define VPD_LEN 512 +#define VPD_BASE 0x400 +#define VPD_BASE_OLD 0 /** * t4_seeprom_wp - enable/disable EEPROM write protection @@ -524,7 +525,7 @@ int t4_seeprom_wp(struct adapter *adapter, bool enable) int get_vpd_params(struct adapter *adapter, struct vpd_params *p) { u32 cclk_param, cclk_val; - int i, ret; + int i, ret, addr; int ec, sn; u8 *vpd, csum; unsigned int vpdr_len, kw_offset, id_len; @@ -533,7 +534,12 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p) if (!vpd) return -ENOMEM; - ret = pci_read_vpd(adapter->pdev, VPD_BASE, VPD_LEN, vpd); + ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd); + if (ret < 0) + goto out; + addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD; + + ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd); if (ret < 0) goto out; -- cgit v1.2.3 From 3f315bef23075ea8a98a6fe4221a83b83456d970 Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Mon, 11 Mar 2013 00:21:48 +0000 Subject: netconsole: don't call __netpoll_cleanup() while atomic __netpoll_cleanup() is called in netconsole_netdev_event() while holding a spinlock. Release/acquire the spinlock before/after it and restart the loop. Also, disable the netconsole completely, because we won't have chance after the restart of the loop, and might end up in a situation where nt->enabled == 1 and nt->np.dev == NULL. Signed-off-by: Veaceslav Falico Acked-by: Neil Horman Signed-off-by: David S. Miller --- drivers/net/netconsole.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 37add21a3d7d..59ac143dec25 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -666,6 +666,7 @@ static int netconsole_netdev_event(struct notifier_block *this, goto done; spin_lock_irqsave(&target_list_lock, flags); +restart: list_for_each_entry(nt, &target_list, list) { netconsole_target_get(nt); if (nt->np.dev == dev) { @@ -678,15 +679,17 @@ static int netconsole_netdev_event(struct notifier_block *this, case NETDEV_UNREGISTER: /* * rtnl_lock already held + * we might sleep in __netpoll_cleanup() */ - if (nt->np.dev) { - __netpoll_cleanup(&nt->np); - dev_put(nt->np.dev); - nt->np.dev = NULL; - } + spin_unlock_irqrestore(&target_list_lock, flags); + __netpoll_cleanup(&nt->np); + spin_lock_irqsave(&target_list_lock, flags); + dev_put(nt->np.dev); + nt->np.dev = NULL; nt->enabled = 0; stopped = true; - break; + netconsole_target_put(nt); + goto restart; } } netconsole_target_put(nt); -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 09081e5b47f6842669bb645e015deedf191244f4 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Sat, 9 Mar 2013 12:43:54 +0100 Subject: tty: serial: mpc5xxx: fix PSC clock name bug mpc512x platform clock code names PSC clocks as "pscX_mclk" but the driver tries to get "pscX_clk" clock and this results in errors like: mpc52xx-psc-uart 80011700.psc: Failed to get PSC clock entry! The problem appears when opening ttyPSC devices other than the system's serial console. Since getting and enabling the PSC clock fails, uart port startup doesn't succeed and tty flag TTY_IO_ERROR remains set causing further errors in tty ioctls, i.e. 'strace stty -F /dev/ttyPSC1' shows: open("/dev/ttyPSC1", O_RDONLY|O_NONBLOCK|O_LARGEFILE) = 3 dup2(3, 0) = 0 close(3) = 0 fcntl64(0, F_GETFL) = 0x10800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE) fcntl64(0, F_SETFL, O_RDONLY|O_LARGEFILE) = 0 ioctl(0, TCGETS, 0xbff89038) = -1 EIO (Input/output error) Only request PSC clock names that the platform actually provides. Signed-off-by: Anatolij Gustschin Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/mpc52xx_uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/mpc52xx_uart.c b/drivers/tty/serial/mpc52xx_uart.c index c0e1fad51be7..018bad922554 100644 --- a/drivers/tty/serial/mpc52xx_uart.c +++ b/drivers/tty/serial/mpc52xx_uart.c @@ -550,7 +550,7 @@ static int mpc512x_psc_clock(struct uart_port *port, int enable) return 0; psc_num = (port->mapbase & 0xf00) >> 8; - snprintf(clk_name, sizeof(clk_name), "psc%d_clk", psc_num); + snprintf(clk_name, sizeof(clk_name), "psc%d_mclk", psc_num); psc_clk = clk_get(port->dev, clk_name); if (IS_ERR(psc_clk)) { dev_err(port->dev, "Failed to get PSC clock entry!\n"); -- cgit v1.2.3 From 5771a8051d5ebaac0651a957885f55b5f6221a02 Mon Sep 17 00:00:00 2001 From: Tony Prisk Date: Sat, 9 Mar 2013 18:44:37 +1300 Subject: tty: serial: vt8500: Unneccessary duplicated clock code removed Remove the extra code left over when the serial driver was changed to require a clock. There is no fallback to 24Mhz as a clock is now required. Also remove a second call to of_clk_get which is unnecessary. Signed-off-by: Tony Prisk Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/vt8500_serial.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/vt8500_serial.c b/drivers/tty/serial/vt8500_serial.c index a3f9dd5c9dff..705240e6c4ec 100644 --- a/drivers/tty/serial/vt8500_serial.c +++ b/drivers/tty/serial/vt8500_serial.c @@ -611,14 +611,7 @@ static int vt8500_serial_probe(struct platform_device *pdev) vt8500_port->uart.dev = &pdev->dev; vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF; - vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0); - if (!IS_ERR(vt8500_port->clk)) { - vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); - } else { - /* use the default of 24Mhz if not specified and warn */ - pr_warn("%s: serial clock source not specified\n", __func__); - vt8500_port->uart.uartclk = 24000000; - } + vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk); snprintf(vt8500_port->name, sizeof(vt8500_port->name), "VT8500 UART%d", pdev->id); -- cgit v1.2.3 From e06c93cacb82dd147266fd1bdb2d0a0bd45ff2c1 Mon Sep 17 00:00:00 2001 From: Ley Foon Tan Date: Thu, 7 Mar 2013 10:28:37 +0800 Subject: tty/serial: Add support for Altera serial port Add support for Altera 8250/16550 compatible serial port. Signed-off-by: Ley Foon Tan Cc: stable Signed-off-by: Greg Kroah-Hartman --- .../devicetree/bindings/tty/serial/of-serial.txt | 3 +++ drivers/tty/serial/8250/8250.c | 23 +++++++++++++++++++++- drivers/tty/serial/of_serial.c | 6 ++++++ include/uapi/linux/serial_core.h | 5 ++++- 4 files changed, 35 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/Documentation/devicetree/bindings/tty/serial/of-serial.txt b/Documentation/devicetree/bindings/tty/serial/of-serial.txt index 1e1145ca4f3c..8f01cb190f25 100644 --- a/Documentation/devicetree/bindings/tty/serial/of-serial.txt +++ b/Documentation/devicetree/bindings/tty/serial/of-serial.txt @@ -11,6 +11,9 @@ Required properties: - "nvidia,tegra20-uart" - "nxp,lpc3220-uart" - "ibm,qpace-nwp-serial" + - "altr,16550-FIFO32" + - "altr,16550-FIFO64" + - "altr,16550-FIFO128" - "serial" if the port type is unknown. - reg : offset and length of the register set for the device. - interrupts : should contain uart interrupt. diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 0efc815a4968..661096d25620 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -301,7 +301,28 @@ static const struct serial8250_config uart_config[] = { }, [PORT_8250_CIR] = { .name = "CIR port" - } + }, + [PORT_ALTR_16550_F32] = { + .name = "Altera 16550 FIFO32", + .fifo_size = 32, + .tx_loadsz = 32, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, + [PORT_ALTR_16550_F64] = { + .name = "Altera 16550 FIFO64", + .fifo_size = 64, + .tx_loadsz = 64, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, + [PORT_ALTR_16550_F128] = { + .name = "Altera 16550 FIFO128", + .fifo_size = 128, + .tx_loadsz = 128, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, + .flags = UART_CAP_FIFO | UART_CAP_AFE, + }, }; /* Uart divisor latch read */ diff --git a/drivers/tty/serial/of_serial.c b/drivers/tty/serial/of_serial.c index d5874605682b..b025d5438275 100644 --- a/drivers/tty/serial/of_serial.c +++ b/drivers/tty/serial/of_serial.c @@ -241,6 +241,12 @@ static struct of_device_id of_platform_serial_table[] = { { .compatible = "ns16850", .data = (void *)PORT_16850, }, { .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, }, { .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, }, + { .compatible = "altr,16550-FIFO32", + .data = (void *)PORT_ALTR_16550_F32, }, + { .compatible = "altr,16550-FIFO64", + .data = (void *)PORT_ALTR_16550_F64, }, + { .compatible = "altr,16550-FIFO128", + .data = (void *)PORT_ALTR_16550_F128, }, #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL { .compatible = "ibm,qpace-nwp-serial", .data = (void *)PORT_NWPSERIAL, }, diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index b6a23a483d74..74c2bf7211f8 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -51,7 +51,10 @@ #define PORT_8250_CIR 23 /* CIR infrared port, has its own driver */ #define PORT_XR17V35X 24 /* Exar XR17V35x UARTs */ #define PORT_BRCM_TRUMANAGE 25 -#define PORT_MAX_8250 25 /* max port ID */ +#define PORT_ALTR_16550_F32 26 /* Altera 16550 UART with 32 FIFOs */ +#define PORT_ALTR_16550_F64 27 /* Altera 16550 UART with 64 FIFOs */ +#define PORT_ALTR_16550_F128 28 /* Altera 16550 UART with 128 FIFOs */ +#define PORT_MAX_8250 28 /* max port ID */ /* * ARM specific type numbers. These are not currently guaranteed -- cgit v1.2.3 From d13402a4a944e72612a9ec5c9190e35717c02a9d Mon Sep 17 00:00:00 2001 From: Scott Ashcroft Date: Sun, 3 Mar 2013 21:35:06 +0000 Subject: Fix 4 port and add support for 8 port 'Unknown' PCI serial port cards I've managed to find an 8 port version of the card 4 port card which was discussed here: http://marc.info/?l=linux-serial&m=120760744205314&w=2 Looking back at that thread there were two issues in the original patch. 1) The I/O ports for the UARTs are within BAR2 not BAR0. This can been seen in the original post. 2) A serial quirk isn't needed as these cards have no memory in BAR0 which makes pci_plx9050_init just return. This patch fixes the 4 port support to use BAR2, removes the bogus quirk and adds support for the 8 port card. $ lspci -vvv -n -s 00:08.0 00:08.0 0780: 10b5:9050 (rev 01) Subsystem: 10b5:1588 Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR- Kernel driver in use: serial $ dmesg | grep 0000:00:08.0: [ 0.083320] pci 0000:00:08.0: [10b5:9050] type 0 class 0x000780 [ 0.083355] pci 0000:00:08.0: reg 14: [io 0xff00-0xff7f] [ 0.083369] pci 0000:00:08.0: reg 18: [io 0xfe00-0xfe3f] [ 0.083382] pci 0000:00:08.0: reg 1c: [io 0xfd00-0xfd07] [ 0.083460] pci 0000:00:08.0: PME# supported from D0 D3hot [ 1.212867] 0000:00:08.0: ttyS4 at I/O 0xfe00 (irq = 17) is a 16550A [ 1.233073] 0000:00:08.0: ttyS5 at I/O 0xfe08 (irq = 17) is a 16550A [ 1.253270] 0000:00:08.0: ttyS6 at I/O 0xfe10 (irq = 17) is a 16550A [ 1.273468] 0000:00:08.0: ttyS7 at I/O 0xfe18 (irq = 17) is a 16550A [ 1.293666] 0000:00:08.0: ttyS8 at I/O 0xfe20 (irq = 17) is a 16550A [ 1.313863] 0000:00:08.0: ttyS9 at I/O 0xfe28 (irq = 17) is a 16550A [ 1.334061] 0000:00:08.0: ttyS10 at I/O 0xfe30 (irq = 17) is a 16550A [ 1.354258] 0000:00:08.0: ttyS11 at I/O 0xfe38 (irq = 17) is a 16550A Signed-off-by: Scott Ashcroft Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 791c5a77ec61..85c6bf904feb 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1571,6 +1571,7 @@ pci_wch_ch353_setup(struct serial_private *priv, /* Unknown vendors/cards - this should not be in linux/pci_ids.h */ #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584 0x1584 +#define PCI_SUBDEVICE_ID_UNKNOWN_0x1588 0x1588 /* * Master list of serial port init/setup/exit quirks. @@ -1850,15 +1851,6 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .setup = pci_default_setup, .exit = pci_plx9050_exit, }, - { - .vendor = PCI_VENDOR_ID_PLX, - .device = PCI_DEVICE_ID_PLX_9050, - .subvendor = PCI_VENDOR_ID_PLX, - .subdevice = PCI_SUBDEVICE_ID_UNKNOWN_0x1584, - .init = pci_plx9050_init, - .setup = pci_default_setup, - .exit = pci_plx9050_exit, - }, { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_ROMULUS, @@ -3733,7 +3725,12 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_VENDOR_ID_PLX, PCI_SUBDEVICE_ID_UNKNOWN_0x1584, 0, 0, - pbn_b0_4_115200 }, + pbn_b2_4_115200 }, + /* Unknown card - subdevice 0x1588 */ + { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, + PCI_VENDOR_ID_PLX, + PCI_SUBDEVICE_ID_UNKNOWN_0x1588, 0, 0, + pbn_b2_8_115200 }, { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050, PCI_SUBVENDOR_ID_KEYSPAN, PCI_SUBDEVICE_ID_KEYSPAN_SX2, 0, 0, -- cgit v1.2.3 From 8d2f8cd424ca0b99001f3ff4f5db87c4e525f366 Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Fri, 1 Mar 2013 11:47:20 +0800 Subject: serial: 8250_pci: add support for another kind of NetMos Technology PCI 9835 Multi-I/O Controller 01:08.0 Communication controller: NetMos Technology PCI 9835 Multi-I/O Controller (rev 01) Subsystem: Device [1000:0012] Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- SERR- Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 85c6bf904feb..aa76825229dc 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -4788,6 +4788,10 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_VENDOR_ID_IBM, 0x0299, 0, 0, pbn_b0_bt_2_115200 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, + 0x1000, 0x0012, + 0, 0, pbn_b0_bt_2_115200 }, + { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9901, 0xA000, 0x1000, 0, 0, pbn_b0_1_115200 }, -- cgit v1.2.3 From 064256feab4f94d2dc894b181e2f82769966f6c7 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Sun, 24 Feb 2013 14:08:39 +0100 Subject: serial: bcm63xx_uart: fix compilation after "TTY: switch tty_insert_flip_char" 92a19f9cec9a80ad93c06e115822deb729e2c6ad introduced a local variable with the same name as the argument to bcm_uart_do_rx, breaking compilation. Fix this by renaming the new variable and its uses where expected. Signed-off-by: Jonas Gorski Acked-by: Jiri Slaby Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/bcm63xx_uart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/bcm63xx_uart.c b/drivers/tty/serial/bcm63xx_uart.c index 719594e5fc21..52a3ecd40421 100644 --- a/drivers/tty/serial/bcm63xx_uart.c +++ b/drivers/tty/serial/bcm63xx_uart.c @@ -235,7 +235,7 @@ static const char *bcm_uart_type(struct uart_port *port) */ static void bcm_uart_do_rx(struct uart_port *port) { - struct tty_port *port = &port->state->port; + struct tty_port *tty_port = &port->state->port; unsigned int max_count; /* limit number of char read in interrupt, should not be @@ -260,7 +260,7 @@ static void bcm_uart_do_rx(struct uart_port *port) bcm_uart_writel(port, val, UART_CTL_REG); port->icount.overrun++; - tty_insert_flip_char(port, 0, TTY_OVERRUN); + tty_insert_flip_char(tty_port, 0, TTY_OVERRUN); } if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY))) @@ -299,11 +299,11 @@ static void bcm_uart_do_rx(struct uart_port *port) if ((cstat & port->ignore_status_mask) == 0) - tty_insert_flip_char(port, c, flag); + tty_insert_flip_char(tty_port, c, flag); } while (--max_count); - tty_flip_buffer_push(port); + tty_flip_buffer_push(tty_port); } /* -- cgit v1.2.3 From 77e372a3d82e5e4878ce1962207edd766773cc76 Mon Sep 17 00:00:00 2001 From: Sean Young Date: Fri, 22 Feb 2013 16:27:19 +0000 Subject: tty/8250_pnp: serial port detection regression since v3.7 The InsydeH2O BIOS (version dated 09/12/2011) has the following in its pnp resouces for its serial ports: $ cat /sys/bus/pnp/devices/00:0b/resources state = active io disabled irq disabled We do not check if the resources are disabled, and create a bogus ttyS* device. Since commit 835d844d1a28e (8250_pnp: do pnp probe before legacy probe) we get a bogus ttyS0, which prevents the legacy probe from detecting it. Note, the BIOS can also be upgraded, fixing this problem, but for people who can't do that, this fix is needed. Reported-by: Vincent Deffontaines Tested-by: Vincent Deffontaines Signed-off-by: Sean Young Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pnp.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_pnp.c b/drivers/tty/serial/8250/8250_pnp.c index 35d9ab95c5cb..b3455a970a1d 100644 --- a/drivers/tty/serial/8250/8250_pnp.c +++ b/drivers/tty/serial/8250/8250_pnp.c @@ -429,6 +429,7 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct uart_8250_port uart; int ret, line, flags = dev_id->driver_data; + struct resource *res = NULL; if (flags & UNKNOWN_DEV) { ret = serial_pnp_guess_board(dev); @@ -439,11 +440,12 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) memset(&uart, 0, sizeof(uart)); if (pnp_irq_valid(dev, 0)) uart.port.irq = pnp_irq(dev, 0); - if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) { - uart.port.iobase = pnp_port_start(dev, 2); - uart.port.iotype = UPIO_PORT; - } else if (pnp_port_valid(dev, 0)) { - uart.port.iobase = pnp_port_start(dev, 0); + if ((flags & CIR_PORT) && pnp_port_valid(dev, 2)) + res = pnp_get_resource(dev, IORESOURCE_IO, 2); + else if (pnp_port_valid(dev, 0)) + res = pnp_get_resource(dev, IORESOURCE_IO, 0); + if (pnp_resource_enabled(res)) { + uart.port.iobase = res->start; uart.port.iotype = UPIO_PORT; } else if (pnp_mem_valid(dev, 0)) { uart.port.mapbase = pnp_mem_start(dev, 0); -- cgit v1.2.3 From 827aa0d36d486f359808c8fb931cf7a71011a09d Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sat, 9 Mar 2013 23:16:44 +0100 Subject: tty: serial: fix typo "ARCH_S5P6450" This could have been either ARCH_S5P64X0 or CPU_S5P6450. Looking at commit 2555e663b367b8d555e76023f4de3f6338c28d6c ("ARM: S5P64X0: Add UART serial support for S5P6450") - which added this typo - makes clear this should be CPU_S5P6450. Signed-off-by: Paul Bolle Acked-by: Kukjin Kim Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index cf9210db9fa9..40ddbe49a7e2 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -218,7 +218,7 @@ config SERIAL_SAMSUNG_UARTS_4 config SERIAL_SAMSUNG_UARTS int depends on PLAT_SAMSUNG - default 6 if ARCH_S5P6450 + default 6 if CPU_S5P6450 default 4 if SERIAL_SAMSUNG_UARTS_4 || CPU_S3C2416 default 3 help -- cgit v1.2.3 From f2b8dfd9e480c3db3bad0c25c590a5d11b31f4ef Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Sun, 10 Mar 2013 10:33:40 -0400 Subject: serial: 8250: Keep 8250. module options functional after driver rename With commit 835d844d1 (8250_pnp: do pnp probe before legacy probe), the 8250 driver was renamed to 8250_core. This means any existing usage of the 8259. module parameters or as a kernel command line switch is now broken, as the 8250_core driver doesn't parse options belonging to something called "8250". To solve this, we redefine the module options in a dummy function using a redefined MODULE_PARAM_PREFX when built into the kernel. In the case where we're building as a module, we provide an alias to the old 8250 name. The dummy function prevents compiler errors due to global variable redefinitions that happen as part of the module_param_ macro expansions. Signed-off-by: Josh Boyer Acked-by: Jiri Slaby Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c index 661096d25620..cf6a5383748a 100644 --- a/drivers/tty/serial/8250/8250.c +++ b/drivers/tty/serial/8250/8250.c @@ -3417,3 +3417,32 @@ module_param_array(probe_rsa, ulong, &probe_rsa_count, 0444); MODULE_PARM_DESC(probe_rsa, "Probe I/O ports for RSA"); #endif MODULE_ALIAS_CHARDEV_MAJOR(TTY_MAJOR); + +#ifndef MODULE +/* This module was renamed to 8250_core in 3.7. Keep the old "8250" name + * working as well for the module options so we don't break people. We + * need to keep the names identical and the convenient macros will happily + * refuse to let us do that by failing the build with redefinition errors + * of global variables. So we stick them inside a dummy function to avoid + * those conflicts. The options still get parsed, and the redefined + * MODULE_PARAM_PREFIX lets us keep the "8250." syntax alive. + * + * This is hacky. I'm sorry. + */ +static void __used s8250_options(void) +{ +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "8250." + + module_param_cb(share_irqs, ¶m_ops_uint, &share_irqs, 0644); + module_param_cb(nr_uarts, ¶m_ops_uint, &nr_uarts, 0644); + module_param_cb(skip_txen_test, ¶m_ops_uint, &skip_txen_test, 0644); +#ifdef CONFIG_SERIAL_8250_RSA + __module_param_call(MODULE_PARAM_PREFIX, probe_rsa, + ¶m_array_ops, .arr = &__param_arr_probe_rsa, + 0444, -1); +#endif +} +#else +MODULE_ALIAS("8250"); +#endif -- cgit v1.2.3 From c51d41a1dd8f23a06a4ed651ebb9617de7f59368 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Tue, 12 Mar 2013 10:10:32 +0100 Subject: tty: serial: fix typo "SERIAL_S3C2412" The Kconfig symbol SERIAL_S3C2412 got removed in commit da121506eb03ee5daea55404709110b798bd61d9 ("serial: samsung: merge probe() function from all SoC specific extensions"). But it also added a last reference to that symbol. The commit and the tree make clear that CPU_S3C2412 should have been used instead. Signed-off-by: Paul Bolle Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 40ddbe49a7e2..7e7006fd404e 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig @@ -211,7 +211,7 @@ config SERIAL_SAMSUNG config SERIAL_SAMSUNG_UARTS_4 bool depends on PLAT_SAMSUNG - default y if !(CPU_S3C2410 || SERIAL_S3C2412 || CPU_S3C2440 || CPU_S3C2442) + default y if !(CPU_S3C2410 || CPU_S3C2412 || CPU_S3C2440 || CPU_S3C2442) help Internal node for the common case of 4 Samsung compatible UARTs -- cgit v1.2.3 From a57e82a18779ab8a5e5a1f5841cef937cf578913 Mon Sep 17 00:00:00 2001 From: Steve Conklin Date: Thu, 7 Mar 2013 17:19:33 -0600 Subject: usb: serial: Add Rigblaster Advantage to device table The Rigblaster Advantage is an amateur radio interface sold by West Mountain Radio. It contains a cp210x serial interface but the device ID is not in the driver. Signed-off-by: Steve Conklin Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/cp210x.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 67088cebaa1d..4747d1c328ff 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -85,6 +85,7 @@ static const struct usb_device_id id_table[] = { { USB_DEVICE(0x10C4, 0x813F) }, /* Tams Master Easy Control */ { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ + { USB_DEVICE(0x2405, 0x0003) }, /* West Mountain Radio RIGblaster Advantage */ { USB_DEVICE(0x10C4, 0x8156) }, /* B&G H3000 link cable */ { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ { USB_DEVICE(0x10C4, 0x815F) }, /* Timewave HamLinkUSB */ -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From fae8563b25f73dc584a07bcda7a82750ff4f7672 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Wed, 27 Feb 2013 16:50:38 +0000 Subject: sfc: Only use TX push if a single descriptor is to be written Using TX push when notifying the NIC of multiple new descriptors in the ring will very occasionally cause the TX DMA engine to re-use an old descriptor. This can result in a duplicated or partly duplicated packet (new headers with old data), or an IOMMU page fault. This does not happen when the pushed descriptor is the only one written. TX push also provides little latency benefit when a packet requires more than one descriptor. Signed-off-by: Ben Hutchings --- drivers/net/ethernet/sfc/nic.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 0ad790cc473c..eaa8e874a3cb 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -376,7 +376,8 @@ efx_may_push_tx_desc(struct efx_tx_queue *tx_queue, unsigned int write_count) return false; tx_queue->empty_read_count = 0; - return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0; + return ((empty_read_count ^ write_count) & ~EFX_EMPTY_COUNT_VALID) == 0 + && tx_queue->write_count - write_count == 1; } /* For each entry inserted into the software descriptor ring, create a -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 01230551e7c2fb9a1c2519b356d703851049cbe0 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 8 Mar 2013 11:07:59 +0100 Subject: w1-gpio: remove erroneous __exit and __exit_p() Commit 8a1861d997 ("w1-gpio: Simplify & get rid of defines") changed (apparently unknowingly) the driver to a hotpluggable platform-device driver but did not not update the section markers for probe and remove (to __devinit/exit, which have since been removed). A later commit fixed the section mismatch for probe, but left remove marked with __exit. Signed-off-by: Johan Hovold Cc: stable # 3.8 Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/w1-gpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index d39dfa4cc235..012817abb12f 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -158,7 +158,7 @@ static int w1_gpio_probe(struct platform_device *pdev) return err; } -static int __exit w1_gpio_remove(struct platform_device *pdev) +static int w1_gpio_remove(struct platform_device *pdev) { struct w1_bus_master *master = platform_get_drvdata(pdev); struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; @@ -210,7 +210,7 @@ static struct platform_driver w1_gpio_driver = { .of_match_table = of_match_ptr(w1_gpio_dt_ids), }, .probe = w1_gpio_probe, - .remove = __exit_p(w1_gpio_remove), + .remove = w1_gpio_remove, .suspend = w1_gpio_suspend, .resume = w1_gpio_resume, }; -- cgit v1.2.3 From 34ccd8738e34180af34544d2bdd053e60e44a224 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Fri, 8 Mar 2013 11:08:00 +0100 Subject: w1-gpio: fix unused variable warning Commit 8a1861d997 ("w1-gpio: Simplify & get rid of defines") removed the compile guards from the device-tree id table, thereby generating a warning when building without device-tree support. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/w1/masters/w1-gpio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c index 012817abb12f..46d97014342e 100644 --- a/drivers/w1/masters/w1-gpio.c +++ b/drivers/w1/masters/w1-gpio.c @@ -47,11 +47,13 @@ static u8 w1_gpio_read_bit(void *data) return gpio_get_value(pdata->pin) ? 1 : 0; } +#if defined(CONFIG_OF) static struct of_device_id w1_gpio_dt_ids[] = { { .compatible = "w1-gpio" }, {} }; MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids); +#endif static int w1_gpio_probe_dt(struct platform_device *pdev) { -- cgit v1.2.3 From 9d1817cab2f030f6af360e961cc69bb1da8ad765 Mon Sep 17 00:00:00 2001 From: Marcin Jurkowski Date: Sat, 2 Mar 2013 14:50:15 +0100 Subject: w1: fix oops when w1_search is called from netlink connector On Sat, Mar 02, 2013 at 10:45:10AM +0100, Sven Geggus wrote: > This is the bad commit I found doing git bisect: > 04f482faf50535229a5a5c8d629cf963899f857c is the first bad commit > commit 04f482faf50535229a5a5c8d629cf963899f857c > Author: Patrick McHardy > Date: Mon Mar 28 08:39:36 2011 +0000 Good job. I was too lazy to bisect for bad commit;) Reading the code I found problematic kthread_should_stop call from netlink connector which causes the oops. After applying a patch, I've been testing owfs+w1 setup for nearly two days and it seems to work very reliable (no hangs, no memleaks etc). More detailed description and possible fix is given below: Function w1_search can be called from either kthread or netlink callback. While the former works fine, the latter causes oops due to kthread_should_stop invocation. This patch adds a check if w1_search is serving netlink command, skipping kthread_should_stop invocation if so. Signed-off-by: Marcin Jurkowski Acked-by: Evgeniy Polyakov Cc: Josh Boyer Tested-by: Sven Geggus Signed-off-by: Greg Kroah-Hartman Cc: stable # 3.0+ --- drivers/w1/w1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 7994d933f040..7ce277d2bb67 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c @@ -924,7 +924,8 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb tmp64 = (triplet_ret >> 2); rn |= (tmp64 << i); - if (kthread_should_stop()) { + /* ensure we're called from kthread and not by netlink callback */ + if (!dev->priv && kthread_should_stop()) { mutex_unlock(&dev->bus_mutex); dev_dbg(&dev->dev, "Abort w1_search\n"); return; -- cgit v1.2.3 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 v1.2.3 From c0f5ecee4e741667b2493c742b60b6218d40b3aa Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 12 Mar 2013 14:52:42 +0100 Subject: USB: cdc-wdm: fix buffer overflow The buffer for responses must not overflow. If this would happen, set a flag, drop the data and return an error after user space has read all remaining data. Signed-off-by: Oliver Neukum CC: stable@kernel.org Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-wdm.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index 5f0cb417b736..122d056d96d5 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -56,6 +56,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_RESPONDING 7 #define WDM_SUSPENDING 8 #define WDM_RESETTING 9 +#define WDM_OVERFLOW 10 #define WDM_MAX 16 @@ -155,6 +156,7 @@ static void wdm_in_callback(struct urb *urb) { struct wdm_device *desc = urb->context; int status = urb->status; + int length = urb->actual_length; spin_lock(&desc->iuspin); clear_bit(WDM_RESPONDING, &desc->flags); @@ -185,9 +187,17 @@ static void wdm_in_callback(struct urb *urb) } desc->rerr = status; - desc->reslength = urb->actual_length; - memmove(desc->ubuf + desc->length, desc->inbuf, desc->reslength); - desc->length += desc->reslength; + if (length + desc->length > desc->wMaxCommand) { + /* The buffer would overflow */ + set_bit(WDM_OVERFLOW, &desc->flags); + } else { + /* we may already be in overflow */ + if (!test_bit(WDM_OVERFLOW, &desc->flags)) { + memmove(desc->ubuf + desc->length, desc->inbuf, length); + desc->length += length; + desc->reslength = length; + } + } skip_error: wake_up(&desc->wait); @@ -435,6 +445,11 @@ retry: rv = -ENODEV; goto err; } + if (test_bit(WDM_OVERFLOW, &desc->flags)) { + clear_bit(WDM_OVERFLOW, &desc->flags); + rv = -ENOBUFS; + goto err; + } i++; if (file->f_flags & O_NONBLOCK) { if (!test_bit(WDM_READ, &desc->flags)) { @@ -478,6 +493,7 @@ retry: spin_unlock_irq(&desc->iuspin); goto retry; } + if (!desc->reslength) { /* zero length read */ dev_dbg(&desc->intf->dev, "%s: zero length - clearing WDM_READ\n", __func__); clear_bit(WDM_READ, &desc->flags); @@ -1004,6 +1020,7 @@ static int wdm_post_reset(struct usb_interface *intf) struct wdm_device *desc = wdm_find_device(intf); int rv; + clear_bit(WDM_OVERFLOW, &desc->flags); clear_bit(WDM_RESETTING, &desc->flags); rv = recover_from_urb_loss(desc); mutex_unlock(&desc->wlock); -- cgit v1.2.3 From 810d601f07ce2481ff776e049c0733ded2abbcc1 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 18 Feb 2013 10:15:03 +0900 Subject: extcon: max8997: Check the pointer of platform data to protect null pointer error This patch check the pointer of platform data to protect kernel panic when platform data is not used and code clean. Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max8997.c | 56 +++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 22 deletions(-) (limited to 'drivers') diff --git a/drivers/extcon/extcon-max8997.c b/drivers/extcon/extcon-max8997.c index e636d950ad6c..69641bcae325 100644 --- a/drivers/extcon/extcon-max8997.c +++ b/drivers/extcon/extcon-max8997.c @@ -712,29 +712,45 @@ static int max8997_muic_probe(struct platform_device *pdev) goto err_irq; } - /* Initialize registers according to platform data */ if (pdata->muic_pdata) { - struct max8997_muic_platform_data *mdata = info->muic_pdata; - - for (i = 0; i < mdata->num_init_data; i++) { - max8997_write_reg(info->muic, mdata->init_data[i].addr, - mdata->init_data[i].data); + struct max8997_muic_platform_data *muic_pdata + = pdata->muic_pdata; + + /* Initialize registers according to platform data */ + for (i = 0; i < muic_pdata->num_init_data; i++) { + max8997_write_reg(info->muic, + muic_pdata->init_data[i].addr, + muic_pdata->init_data[i].data); } - } - /* - * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB - * h/w path of COMP2/COMN1 on CONTROL1 register. - */ - if (pdata->muic_pdata->path_uart) - info->path_uart = pdata->muic_pdata->path_uart; - else - info->path_uart = CONTROL1_SW_UART; + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + if (muic_pdata->path_uart) + info->path_uart = muic_pdata->path_uart; + else + info->path_uart = CONTROL1_SW_UART; - if (pdata->muic_pdata->path_usb) - info->path_usb = pdata->muic_pdata->path_usb; - else + if (muic_pdata->path_usb) + info->path_usb = muic_pdata->path_usb; + else + info->path_usb = CONTROL1_SW_USB; + + /* + * Default delay time for detecting cable state + * after certain time. + */ + if (muic_pdata->detcable_delay_ms) + delay_jiffies = + msecs_to_jiffies(muic_pdata->detcable_delay_ms); + else + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); + } else { + info->path_uart = CONTROL1_SW_UART; info->path_usb = CONTROL1_SW_USB; + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); + } /* Set initial path for UART */ max8997_muic_set_path(info, info->path_uart, true); @@ -751,10 +767,6 @@ static int max8997_muic_probe(struct platform_device *pdev) * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max8997_muic_detect_cable_wq); - if (pdata->muic_pdata->detcable_delay_ms) - delay_jiffies = msecs_to_jiffies(pdata->muic_pdata->detcable_delay_ms); - else - delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); schedule_delayed_work(&info->wq_detcable, delay_jiffies); return 0; -- cgit v1.2.3 From 190d7cfc8632c10bfbfe756f882b6d9cfddfdf6a Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Mon, 18 Feb 2013 10:03:32 +0900 Subject: extcon: max77693: Fix bug of wrong pointer when platform data is not used This patch fix wrong pointer of platform data. If each machine set platform data for h/w path or delay time of workqueue, this driver happen kernel panic related to null pointer. Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max77693.c | 90 +++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 38 deletions(-) (limited to 'drivers') diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index b70e3815c459..fea10624f3e5 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -1045,7 +1045,6 @@ static int max77693_muic_probe(struct platform_device *pdev) { struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); - struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; struct max77693_muic_info *info; int delay_jiffies; int ret; @@ -1145,44 +1144,63 @@ static int max77693_muic_probe(struct platform_device *pdev) goto err_irq; } - /* Initialize MUIC register by using platform data */ - for (i = 0 ; i < muic_pdata->num_init_data ; i++) { - enum max77693_irq_source irq_src = MAX77693_IRQ_GROUP_NR; - - max77693_write_reg(info->max77693->regmap_muic, - muic_pdata->init_data[i].addr, - muic_pdata->init_data[i].data); - - switch (muic_pdata->init_data[i].addr) { - case MAX77693_MUIC_REG_INTMASK1: - irq_src = MUIC_INT1; - break; - case MAX77693_MUIC_REG_INTMASK2: - irq_src = MUIC_INT2; - break; - case MAX77693_MUIC_REG_INTMASK3: - irq_src = MUIC_INT3; - break; + if (pdata->muic_data) { + struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; + + /* Initialize MUIC register by using platform data */ + for (i = 0 ; i < muic_pdata->num_init_data ; i++) { + enum max77693_irq_source irq_src + = MAX77693_IRQ_GROUP_NR; + + max77693_write_reg(info->max77693->regmap_muic, + muic_pdata->init_data[i].addr, + muic_pdata->init_data[i].data); + + switch (muic_pdata->init_data[i].addr) { + case MAX77693_MUIC_REG_INTMASK1: + irq_src = MUIC_INT1; + break; + case MAX77693_MUIC_REG_INTMASK2: + irq_src = MUIC_INT2; + break; + case MAX77693_MUIC_REG_INTMASK3: + irq_src = MUIC_INT3; + break; + } + + if (irq_src < MAX77693_IRQ_GROUP_NR) + info->max77693->irq_masks_cur[irq_src] + = muic_pdata->init_data[i].data; } - if (irq_src < MAX77693_IRQ_GROUP_NR) - info->max77693->irq_masks_cur[irq_src] - = muic_pdata->init_data[i].data; - } + /* + * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB + * h/w path of COMP2/COMN1 on CONTROL1 register. + */ + if (muic_pdata->path_uart) + info->path_uart = muic_pdata->path_uart; + else + info->path_uart = CONTROL1_SW_UART; - /* - * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB - * h/w path of COMP2/COMN1 on CONTROL1 register. - */ - if (muic_pdata->path_uart) - info->path_uart = muic_pdata->path_uart; - else - info->path_uart = CONTROL1_SW_UART; + if (muic_pdata->path_usb) + info->path_usb = muic_pdata->path_usb; + else + info->path_usb = CONTROL1_SW_USB; - if (muic_pdata->path_usb) - info->path_usb = muic_pdata->path_usb; - else + /* + * Default delay time for detecting cable state + * after certain time. + */ + if (muic_pdata->detcable_delay_ms) + delay_jiffies = + msecs_to_jiffies(muic_pdata->detcable_delay_ms); + else + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); + } else { info->path_usb = CONTROL1_SW_USB; + info->path_uart = CONTROL1_SW_UART; + delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); + } /* Set initial path for UART */ max77693_muic_set_path(info, info->path_uart, true); @@ -1208,10 +1226,6 @@ static int max77693_muic_probe(struct platform_device *pdev) * driver should notify cable state to upper layer. */ INIT_DELAYED_WORK(&info->wq_detcable, max77693_muic_detect_cable_wq); - if (muic_pdata->detcable_delay_ms) - delay_jiffies = msecs_to_jiffies(muic_pdata->detcable_delay_ms); - else - delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT); schedule_delayed_work(&info->wq_detcable, delay_jiffies); return ret; -- cgit v1.2.3 From 0ec83bd2460ed6aed0e7f29f9e0633b054621c02 Mon Sep 17 00:00:00 2001 From: Chanwoo Choi Date: Wed, 13 Mar 2013 17:38:57 +0900 Subject: extcon: max77693: Initialize register of MUIC device to bring up it without platform data This patch set default value of MUIC register to bring up MUIC device. If user don't set some initial value for MUIC device through platform data, extcon-max77693 driver use 'default_init_data' to bring up base operation of MAX77693 MUIC device. Signed-off-by: Chanwoo Choi Signed-off-by: Myungjoo Ham --- drivers/extcon/extcon-max77693.c | 93 ++++++++++++++++++++++++++---------- include/linux/mfd/max77693-private.h | 23 +++++++++ 2 files changed, 91 insertions(+), 25 deletions(-) (limited to 'drivers') diff --git a/drivers/extcon/extcon-max77693.c b/drivers/extcon/extcon-max77693.c index fea10624f3e5..8f3c947b0029 100644 --- a/drivers/extcon/extcon-max77693.c +++ b/drivers/extcon/extcon-max77693.c @@ -32,6 +32,38 @@ #define DEV_NAME "max77693-muic" #define DELAY_MS_DEFAULT 20000 /* unit: millisecond */ +/* + * Default value of MAX77693 register to bring up MUIC device. + * If user don't set some initial value for MUIC device through platform data, + * extcon-max77693 driver use 'default_init_data' to bring up base operation + * of MAX77693 MUIC device. + */ +struct max77693_reg_data default_init_data[] = { + { + /* STATUS2 - [3]ChgDetRun */ + .addr = MAX77693_MUIC_REG_STATUS2, + .data = STATUS2_CHGDETRUN_MASK, + }, { + /* INTMASK1 - Unmask [3]ADC1KM,[0]ADCM */ + .addr = MAX77693_MUIC_REG_INTMASK1, + .data = INTMASK1_ADC1K_MASK + | INTMASK1_ADC_MASK, + }, { + /* INTMASK2 - Unmask [0]ChgTypM */ + .addr = MAX77693_MUIC_REG_INTMASK2, + .data = INTMASK2_CHGTYP_MASK, + }, { + /* INTMASK3 - Mask all of interrupts */ + .addr = MAX77693_MUIC_REG_INTMASK3, + .data = 0x0, + }, { + /* CDETCTRL2 */ + .addr = MAX77693_MUIC_REG_CDETCTRL2, + .data = CDETCTRL2_VIDRMEN_MASK + | CDETCTRL2_DXOVPEN_MASK, + }, +}; + enum max77693_muic_adc_debounce_time { ADC_DEBOUNCE_TIME_5MS = 0, ADC_DEBOUNCE_TIME_10MS, @@ -1046,6 +1078,8 @@ static int max77693_muic_probe(struct platform_device *pdev) struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent); struct max77693_platform_data *pdata = dev_get_platdata(max77693->dev); struct max77693_muic_info *info; + struct max77693_reg_data *init_data; + int num_init_data; int delay_jiffies; int ret; int i; @@ -1144,35 +1178,44 @@ static int max77693_muic_probe(struct platform_device *pdev) goto err_irq; } + + /* Initialize MUIC register by using platform data or default data */ if (pdata->muic_data) { - struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; + init_data = pdata->muic_data->init_data; + num_init_data = pdata->muic_data->num_init_data; + } else { + init_data = default_init_data; + num_init_data = ARRAY_SIZE(default_init_data); + } + + for (i = 0 ; i < num_init_data ; i++) { + enum max77693_irq_source irq_src + = MAX77693_IRQ_GROUP_NR; - /* Initialize MUIC register by using platform data */ - for (i = 0 ; i < muic_pdata->num_init_data ; i++) { - enum max77693_irq_source irq_src - = MAX77693_IRQ_GROUP_NR; - - max77693_write_reg(info->max77693->regmap_muic, - muic_pdata->init_data[i].addr, - muic_pdata->init_data[i].data); - - switch (muic_pdata->init_data[i].addr) { - case MAX77693_MUIC_REG_INTMASK1: - irq_src = MUIC_INT1; - break; - case MAX77693_MUIC_REG_INTMASK2: - irq_src = MUIC_INT2; - break; - case MAX77693_MUIC_REG_INTMASK3: - irq_src = MUIC_INT3; - break; - } - - if (irq_src < MAX77693_IRQ_GROUP_NR) - info->max77693->irq_masks_cur[irq_src] - = muic_pdata->init_data[i].data; + max77693_write_reg(info->max77693->regmap_muic, + init_data[i].addr, + init_data[i].data); + + switch (init_data[i].addr) { + case MAX77693_MUIC_REG_INTMASK1: + irq_src = MUIC_INT1; + break; + case MAX77693_MUIC_REG_INTMASK2: + irq_src = MUIC_INT2; + break; + case MAX77693_MUIC_REG_INTMASK3: + irq_src = MUIC_INT3; + break; } + if (irq_src < MAX77693_IRQ_GROUP_NR) + info->max77693->irq_masks_cur[irq_src] + = init_data[i].data; + } + + if (pdata->muic_data) { + struct max77693_muic_platform_data *muic_pdata = pdata->muic_data; + /* * Default usb/uart path whether UART/USB or AUX_UART/AUX_USB * h/w path of COMP2/COMN1 on CONTROL1 register. diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h index 5b18ecde69b5..1aa4f13cdfa6 100644 --- a/include/linux/mfd/max77693-private.h +++ b/include/linux/mfd/max77693-private.h @@ -106,6 +106,29 @@ enum max77693_muic_reg { MAX77693_MUIC_REG_END, }; +/* MAX77693 INTMASK1~2 Register */ +#define INTMASK1_ADC1K_SHIFT 3 +#define INTMASK1_ADCERR_SHIFT 2 +#define INTMASK1_ADCLOW_SHIFT 1 +#define INTMASK1_ADC_SHIFT 0 +#define INTMASK1_ADC1K_MASK (1 << INTMASK1_ADC1K_SHIFT) +#define INTMASK1_ADCERR_MASK (1 << INTMASK1_ADCERR_SHIFT) +#define INTMASK1_ADCLOW_MASK (1 << INTMASK1_ADCLOW_SHIFT) +#define INTMASK1_ADC_MASK (1 << INTMASK1_ADC_SHIFT) + +#define INTMASK2_VIDRM_SHIFT 5 +#define INTMASK2_VBVOLT_SHIFT 4 +#define INTMASK2_DXOVP_SHIFT 3 +#define INTMASK2_DCDTMR_SHIFT 2 +#define INTMASK2_CHGDETRUN_SHIFT 1 +#define INTMASK2_CHGTYP_SHIFT 0 +#define INTMASK2_VIDRM_MASK (1 << INTMASK2_VIDRM_SHIFT) +#define INTMASK2_VBVOLT_MASK (1 << INTMASK2_VBVOLT_SHIFT) +#define INTMASK2_DXOVP_MASK (1 << INTMASK2_DXOVP_SHIFT) +#define INTMASK2_DCDTMR_MASK (1 << INTMASK2_DCDTMR_SHIFT) +#define INTMASK2_CHGDETRUN_MASK (1 << INTMASK2_CHGDETRUN_SHIFT) +#define INTMASK2_CHGTYP_MASK (1 << INTMASK2_CHGTYP_SHIFT) + /* MAX77693 MUIC - STATUS1~3 Register */ #define STATUS1_ADC_SHIFT (0) #define STATUS1_ADCLOW_SHIFT (5) -- cgit v1.2.3 From d35162f89b8f00537d7b240b76d2d0e8b8d29aa0 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 12 Mar 2013 06:31:19 +0000 Subject: net: ethernet: cpsw: fix usage of cpdma_check_free_tx_desc() Commit fae50823d0 ("net: ethernet: davinci_cpdma: Add boundary for rx and tx descriptors") introduced a function to check the current allocation state of tx packets. The return value is taken into account to stop the netqork queue on the adapter in case there are no free slots. However, cpdma_check_free_tx_desc() returns 'true' if there is room in the bitmap, not 'false', so the usage of the function is wrong. Signed-off-by: Daniel Mack Cc: Mugunthan V N Reported-by: Sven Neumann Reported-by: Andreas Fenkart Tested-by: Mugunthan V N Acked-by: Mugunthan V N Tested-by: Andreas Fenkart Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpsw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c index 01ffbc486982..75c48558e6fd 100644 --- a/drivers/net/ethernet/ti/cpsw.c +++ b/drivers/net/ethernet/ti/cpsw.c @@ -905,7 +905,7 @@ static netdev_tx_t cpsw_ndo_start_xmit(struct sk_buff *skb, /* If there is no more tx desc left free then we need to * tell the kernel to stop sending us tx frames. */ - if (unlikely(cpdma_check_free_tx_desc(priv->txch))) + if (unlikely(!cpdma_check_free_tx_desc(priv->txch))) netif_stop_queue(ndev); return NETDEV_TX_OK; -- cgit v1.2.3 From 876254ae2758d50dcb08c7bd00caf6a806571178 Mon Sep 17 00:00:00 2001 From: Veaceslav Falico Date: Tue, 12 Mar 2013 06:31:32 +0000 Subject: bonding: don't call update_speed_duplex() under spinlocks bond_update_speed_duplex() might sleep while calling underlying slave's routines. Move it out of atomic context in bond_enslave() and remove it from bond_miimon_commit() - it was introduced by commit 546add79, however when the slave interfaces go up/change state it's their responsibility to fire NETDEV_UP/NETDEV_CHANGE events so that bonding can properly update their speed. I've tested it on all combinations of ifup/ifdown, autoneg/speed/duplex changes, remote-controlled and local, on (not) MII-based cards. All changes are visible. Signed-off-by: Veaceslav Falico Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 8b4e96e01d6c..6bbd90e1123c 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -1746,6 +1746,8 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) bond_compute_features(bond); + bond_update_speed_duplex(new_slave); + read_lock(&bond->lock); new_slave->last_arp_rx = jiffies - @@ -1798,8 +1800,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) new_slave->link == BOND_LINK_DOWN ? "DOWN" : (new_slave->link == BOND_LINK_UP ? "UP" : "BACK")); - bond_update_speed_duplex(new_slave); - if (USES_PRIMARY(bond->params.mode) && bond->params.primary[0]) { /* if there is a primary slave, remember it */ if (strcmp(bond->params.primary, new_slave->dev->name) == 0) { @@ -2374,8 +2374,6 @@ static void bond_miimon_commit(struct bonding *bond) bond_set_backup_slave(slave); } - bond_update_speed_duplex(slave); - pr_info("%s: link status definitely up for interface %s, %u Mbps %s duplex.\n", bond->dev->name, slave->dev->name, slave->speed, slave->duplex ? "full" : "half"); -- cgit v1.2.3 From a79eac7165ed62114e6ca197195aa5060a54f137 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 5 Feb 2013 14:35:11 +0100 Subject: atmel_lcdfb: fix 16-bpp modes on older SOCs Fix regression introduced by commit 787f9fd23283 ("atmel_lcdfb: support 16bit BGR:565 mode, remove unsupported 15bit modes") which broke 16-bpp modes for older SOCs which use IBGR:555 (msb is intensity) rather than BGR:565. Use SOC-type to determine the pixel layout. Tested on at91sam9263 and at91sam9g45. Cc: Acked-by: Peter Korsgaard Signed-off-by: Johan Hovold Signed-off-by: Nicolas Ferre --- drivers/video/atmel_lcdfb.c | 22 +++++++++++++++------- include/video/atmel_lcdc.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 12cf5f31ee8f..025428e04c33 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -422,17 +422,22 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, = var->bits_per_pixel; break; case 16: + /* Older SOCs use IBGR:555 rather than BGR:565. */ + if (sinfo->have_intensity_bit) + var->green.length = 5; + else + var->green.length = 6; + if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB) { - /* RGB:565 mode */ - var->red.offset = 11; + /* RGB:5X5 mode */ + var->red.offset = var->green.length + 5; var->blue.offset = 0; } else { - /* BGR:565 mode */ + /* BGR:5X5 mode */ var->red.offset = 0; - var->blue.offset = 11; + var->blue.offset = var->green.length + 5; } var->green.offset = 5; - var->green.length = 6; var->red.length = var->blue.length = 5; break; case 32: @@ -679,8 +684,7 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red, case FB_VISUAL_PSEUDOCOLOR: if (regno < 256) { - if (cpu_is_at91sam9261() || cpu_is_at91sam9263() - || cpu_is_at91sam9rl()) { + if (sinfo->have_intensity_bit) { /* old style I+BGR:555 */ val = ((red >> 11) & 0x001f); val |= ((green >> 6) & 0x03e0); @@ -870,6 +874,10 @@ 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; + } strcpy(info->fix.id, sinfo->pdev->name); info->flags = ATMEL_LCDFB_FBINFO_DEFAULT; diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h index 28447f1594fa..5f0e234026c0 100644 --- a/include/video/atmel_lcdc.h +++ b/include/video/atmel_lcdc.h @@ -62,6 +62,7 @@ struct atmel_lcdfb_info { void (*atmel_lcdfb_power_control)(int on); struct fb_monspecs *default_monspecs; u32 pseudo_palette[16]; + bool have_intensity_bit; }; #define ATMEL_LCDC_DMABADDR1 0x00 -- cgit v1.2.3 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 v1.2.3 From 7c6cdead7cc9a99650d15497aae47d7472217eb1 Mon Sep 17 00:00:00 2001 From: Nithin Sujir Date: Tue, 12 Mar 2013 15:32:48 +0000 Subject: tg3: 5715 does not link up when autoneg off Commit d13ba512cbba7de5d55d7a3b2aae7d83c8921457 ("tg3: Remove SPEED_UNKNOWN checks") cleaned up the autoneg advertisement by removing some dead code. One effect of this change was that the advertisement register would not be updated if autoneg is turned off. This exposed a bug on the 5715 device w.r.t linking. The 5715 defaults to advertise only 10Mb Full duplex. But with autoneg disabled, it needs the configured speed enabled in the advertisement register to link up. This patch adds the work around to advertise all speeds on the 5715 when autoneg is disabled. Reported-by: Marcin Miotk 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 | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 93729f942358..67d2663b3974 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -4130,6 +4130,14 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tp->link_config.active_speed = tp->link_config.speed; tp->link_config.active_duplex = tp->link_config.duplex; + if (tg3_asic_rev(tp) == ASIC_REV_5714) { + /* With autoneg disabled, 5715 only links up when the + * advertisement register has the configured speed + * enabled. + */ + tg3_writephy(tp, MII_ADVERTISE, ADVERTISE_ALL); + } + bmcr = 0; switch (tp->link_config.speed) { default: -- cgit v1.2.3 From b701f16dd490d3f346724050f17d60beda094998 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Wed, 13 Mar 2013 02:25:17 +0000 Subject: net: qmi_wwan: set correct altsetting for Gobi 1K devices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit bd877e4 ("net: qmi_wwan: use a single bind function for all device types") made Gobi 1K devices fail probing. Using the number of endpoints in the default altsetting to decide whether the function use one or two interfaces is wrong. Other altsettings may provide more endpoints. With Gobi 1K devices, USB interface #3's altsetting is 0 by default, but altsetting 0 only provides one interrupt endpoint and is not sufficent for QMI. Altsetting 1 provides all 3 endpoints required for qmi_wwan and works with QMI. Gobi 1K layout for intf#3 is: Interface Descriptor: 255/255/255 bInterfaceNumber 3 bAlternateSetting 0 Endpoint Descriptor: Interrupt IN Interface Descriptor: 255/255/255 bInterfaceNumber 3 bAlternateSetting 1 Endpoint Descriptor: Interrupt IN Endpoint Descriptor: Bulk IN Endpoint Descriptor: Bulk OUT Prior to commit bd877e4, we would call usbnet_get_endpoints before giving up finding enough endpoints. Removing the early endpoint number test and the strict functional descriptor requirement allow qmi_wwan_bind to continue until usbnet_get_endpoints has made the final attempt to collect endpoints. This restores the behaviour from before commit bd877e4 without losing the added benefit of using a single bind function. The driver has always required a CDC Union functional descriptor for two-interface functions. Using the existence of this descriptor to detect two-interface functions is the logically correct method. Reported-by: Dan Williams Signed-off-by: Bjørn Mork Tested-by: Dan Williams Signed-off-by: David S. Miller --- drivers/net/usb/qmi_wwan.c | 49 +++++++++++++++------------------------------- 1 file changed, 16 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index efb5c7c33a28..968d5d50751d 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c @@ -139,16 +139,9 @@ static int qmi_wwan_bind(struct usbnet *dev, struct usb_interface *intf) BUILD_BUG_ON((sizeof(((struct usbnet *)0)->data) < sizeof(struct qmi_wwan_state))); - /* control and data is shared? */ - if (intf->cur_altsetting->desc.bNumEndpoints == 3) { - info->control = intf; - info->data = intf; - goto shared; - } - - /* else require a single interrupt status endpoint on control intf */ - if (intf->cur_altsetting->desc.bNumEndpoints != 1) - goto err; + /* set up initial state */ + info->control = intf; + info->data = intf; /* and a number of CDC descriptors */ while (len > 3) { @@ -207,25 +200,14 @@ next_desc: buf += h->bLength; } - /* did we find all the required ones? */ - if (!(found & (1 << USB_CDC_HEADER_TYPE)) || - !(found & (1 << USB_CDC_UNION_TYPE))) { - dev_err(&intf->dev, "CDC functional descriptors missing\n"); - goto err; - } - - /* verify CDC Union */ - if (desc->bInterfaceNumber != cdc_union->bMasterInterface0) { - dev_err(&intf->dev, "bogus CDC Union: master=%u\n", cdc_union->bMasterInterface0); - goto err; - } - - /* need to save these for unbind */ - info->control = intf; - info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); - if (!info->data) { - dev_err(&intf->dev, "bogus CDC Union: slave=%u\n", cdc_union->bSlaveInterface0); - goto err; + /* Use separate control and data interfaces if we found a CDC Union */ + if (cdc_union) { + info->data = usb_ifnum_to_if(dev->udev, cdc_union->bSlaveInterface0); + if (desc->bInterfaceNumber != cdc_union->bMasterInterface0 || !info->data) { + dev_err(&intf->dev, "bogus CDC Union: master=%u, slave=%u\n", + cdc_union->bMasterInterface0, cdc_union->bSlaveInterface0); + goto err; + } } /* errors aren't fatal - we can live with the dynamic address */ @@ -235,11 +217,12 @@ next_desc: } /* claim data interface and set it up */ - status = usb_driver_claim_interface(driver, info->data, dev); - if (status < 0) - goto err; + if (info->control != info->data) { + status = usb_driver_claim_interface(driver, info->data, dev); + if (status < 0) + goto err; + } -shared: status = qmi_wwan_register_subdriver(dev); if (status < 0 && info->control != info->data) { usb_set_intfdata(info->data, NULL); -- cgit v1.2.3 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 v1.2.3 From 3f8bc5e4da29c7e05edeca6b475abb4fb01a5a13 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 13 Mar 2013 09:58:18 -0500 Subject: qcserial: bind to DM/DIAG port on Gobi 1K devices Turns out we just need altsetting 1 and then we can talk to it. Signed-off-by: Dan Williams Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/qcserial.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 24662547dc5b..59b32b782126 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c @@ -197,12 +197,15 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) if (is_gobi1k) { /* Gobi 1K USB layout: - * 0: serial port (doesn't respond) + * 0: DM/DIAG (use libqcdm from ModemManager for communication) * 1: serial port (doesn't respond) * 2: AT-capable modem port * 3: QMI/net */ - if (ifnum == 2) + if (ifnum == 0) { + dev_dbg(dev, "Gobi 1K DM/DIAG interface found\n"); + altsetting = 1; + } else if (ifnum == 2) dev_dbg(dev, "Modem port found\n"); else altsetting = -1; -- cgit v1.2.3 From 6a40cdd5440d7b61a349bc04e85eed4fa7c24a3c Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 5 Mar 2013 14:58:53 +0800 Subject: pinctrl: abx500: Fix checking if pin use AlternateFunction register It's pointless to check "af.alt_bit1 == UNUSED" twice. This looks like a copy-paste bug, I think what we want is to check if *both* af.alt_bit1 and af.alt_bit2 are UNUSED. Signed-off-by: Axel Lin Acked-by: Patrice Chotard Signed-off-by: Linus Walleij --- drivers/pinctrl/pinctrl-abx500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinctrl-abx500.c b/drivers/pinctrl/pinctrl-abx500.c index caecdd373061..c542a97c82f3 100644 --- a/drivers/pinctrl/pinctrl-abx500.c +++ b/drivers/pinctrl/pinctrl-abx500.c @@ -422,7 +422,7 @@ static u8 abx500_get_mode(struct pinctrl_dev *pctldev, struct gpio_chip *chip, } /* check if pin use AlternateFunction register */ - if ((af.alt_bit1 == UNUSED) && (af.alt_bit1 == UNUSED)) + if ((af.alt_bit1 == UNUSED) && (af.alt_bit2 == UNUSED)) return mode; /* * if pin GPIOSEL bit is set and pin supports alternate function, -- cgit v1.2.3 From 53ded8191e81507da0786ac45152eebb68d25d0c Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Wed, 13 Mar 2013 03:18:18 +0100 Subject: pinctrl: Print the correct information in debugfs pinconf-state file A bad copy&paste resulted in the debugfs pinconf-state file printing the pin name instead of the state name. Fix it. Signed-off-by: Laurent Pinchart Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index ac8d382a79bb..d611ecfcbf70 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -622,7 +622,7 @@ static const struct file_operations pinconf_dbg_pinname_fops = { static int pinconf_dbg_state_print(struct seq_file *s, void *d) { if (strlen(dbg_state_name)) - seq_printf(s, "%s\n", dbg_pinname); + seq_printf(s, "%s\n", dbg_state_name); else seq_printf(s, "No pin state set\n"); return 0; -- cgit v1.2.3 From 5818a46a999ad9546e68e8765a3ca1d9d87f9b4a Mon Sep 17 00:00:00 2001 From: John Crispin Date: Wed, 13 Mar 2013 13:20:15 +0100 Subject: rt2x00: fix rt2x00 to work with the new ralink SoC config symbols Since v3.9-rc1 the kernel has basic support for Ralink WiSoC. The config symbols are named slightly different than before. Fix the rt2x00 to match the new symbols. The commit causing this breakage is: commit ae2b5bb6570481b50a7175c64176b82da0a81836 Author: John Crispin Date: Sun Jan 20 22:05:30 2013 +0100 MIPS: ralink: adds Kbuild files Signed-off-by: John Crispin Acked-by: Gertjan van Wingerde Signed-off-by: John W. Linville --- drivers/net/wireless/rt2x00/Kconfig | 4 ++-- drivers/net/wireless/rt2x00/rt2800pci.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig index 44d6ead43341..2bf4efa33186 100644 --- a/drivers/net/wireless/rt2x00/Kconfig +++ b/drivers/net/wireless/rt2x00/Kconfig @@ -55,10 +55,10 @@ config RT61PCI config RT2800PCI tristate "Ralink rt27xx/rt28xx/rt30xx (PCI/PCIe/PCMCIA) support" - depends on PCI || RALINK_RT288X || RALINK_RT305X + depends on PCI || SOC_RT288X || SOC_RT305X select RT2800_LIB select RT2X00_LIB_PCI if PCI - select RT2X00_LIB_SOC if RALINK_RT288X || RALINK_RT305X + select RT2X00_LIB_SOC if SOC_RT288X || SOC_RT305X select RT2X00_LIB_FIRMWARE select RT2X00_LIB_CRYPTO select CRC_CCITT diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index 48a01aa21f1c..ded73da4de0b 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c @@ -89,7 +89,7 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token) rt2x00pci_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0); } -#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) static int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { void __iomem *base_addr = ioremap(0x1F040000, EEPROM_SIZE); @@ -107,7 +107,7 @@ static inline int rt2800pci_read_eeprom_soc(struct rt2x00_dev *rt2x00dev) { return -ENOMEM; } -#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ +#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */ #ifdef CONFIG_PCI static void rt2800pci_eepromregister_read(struct eeprom_93cx6 *eeprom) @@ -1177,7 +1177,7 @@ MODULE_DEVICE_TABLE(pci, rt2800pci_device_table); #endif /* CONFIG_PCI */ MODULE_LICENSE("GPL"); -#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) static int rt2800soc_probe(struct platform_device *pdev) { return rt2x00soc_probe(pdev, &rt2800pci_ops); @@ -1194,7 +1194,7 @@ static struct platform_driver rt2800soc_driver = { .suspend = rt2x00soc_suspend, .resume = rt2x00soc_resume, }; -#endif /* CONFIG_RALINK_RT288X || CONFIG_RALINK_RT305X */ +#endif /* CONFIG_SOC_RT288X || CONFIG_SOC_RT305X */ #ifdef CONFIG_PCI static int rt2800pci_probe(struct pci_dev *pci_dev, @@ -1217,7 +1217,7 @@ static int __init rt2800pci_init(void) { int ret = 0; -#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) ret = platform_driver_register(&rt2800soc_driver); if (ret) return ret; @@ -1225,7 +1225,7 @@ static int __init rt2800pci_init(void) #ifdef CONFIG_PCI ret = pci_register_driver(&rt2800pci_driver); if (ret) { -#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif return ret; @@ -1240,7 +1240,7 @@ static void __exit rt2800pci_exit(void) #ifdef CONFIG_PCI pci_unregister_driver(&rt2800pci_driver); #endif -#if defined(CONFIG_RALINK_RT288X) || defined(CONFIG_RALINK_RT305X) +#if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X) platform_driver_unregister(&rt2800soc_driver); #endif } -- cgit v1.2.3 From 9437a248e7cac427c898bdb11bd1ac6844a1ead4 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Wed, 13 Mar 2013 10:28:13 -0500 Subject: rtlwifi: rtl8192cu: Fix problem that prevents reassociation The driver was failing to clear the BSSID when a disconnect happened. That prevented a reconnection. This problem is reported at https://bugzilla.redhat.com/show_bug.cgi?id=789605, https://bugzilla.redhat.com/show_bug.cgi?id=866786, https://bugzilla.redhat.com/show_bug.cgi?id=906734, and https://bugzilla.kernel.org/show_bug.cgi?id=46171. Thanks to Jussi Kivilinna for making the critical observation that led to the solution. Reported-by: Jussi Kivilinna Tested-by: Jussi Kivilinna Tested-by: Alessandro Lannocca Signed-off-by: Larry Finger Cc: Stable Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | 87 ++++++++++++----------------- 1 file changed, 35 insertions(+), 52 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 3c6e18c38e30..c08d0f4c5f3d 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c @@ -1376,75 +1376,58 @@ void rtl92cu_card_disable(struct ieee80211_hw *hw) } void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) -{ - /* dummy routine needed for callback from rtl_op_configure_filter() */ -} - -/*========================================================================== */ - -static void _rtl92cu_set_check_bssid(struct ieee80211_hw *hw, - enum nl80211_iftype type) { struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); struct rtl_hal *rtlhal = rtl_hal(rtlpriv); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u8 filterout_non_associated_bssid = false; + u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR); - switch (type) { - case NL80211_IFTYPE_ADHOC: - case NL80211_IFTYPE_STATION: - filterout_non_associated_bssid = true; - break; - case NL80211_IFTYPE_UNSPECIFIED: - case NL80211_IFTYPE_AP: - default: - break; - } - if (filterout_non_associated_bssid) { + if (rtlpriv->psc.rfpwr_state != ERFON) + return; + + if (check_bssid) { + u8 tmp; if (IS_NORMAL_CHIP(rtlhal->version)) { - switch (rtlphy->current_io_type) { - case IO_CMD_RESUME_DM_BY_SCAN: - reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_RCR, (u8 *)(®_rcr)); - /* enable update TSF */ - _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); - rtlpriv->cfg->ops->set_hw_reg(hw, - HW_VAR_RCR, (u8 *)(®_rcr)); - /* disable update TSF */ - _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); - break; - } + reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); + tmp = BIT(4); } else { - reg_rcr |= (RCR_CBSSID); - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *)(®_rcr)); - _rtl92cu_set_bcn_ctrl_reg(hw, 0, (BIT(4)|BIT(5))); + reg_rcr |= RCR_CBSSID; + tmp = BIT(4) | BIT(5); } - } else if (filterout_non_associated_bssid == false) { + rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, + (u8 *) (®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp); + } else { + u8 tmp; if (IS_NORMAL_CHIP(rtlhal->version)) { - reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *)(®_rcr)); - _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); + reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); + tmp = BIT(4); } else { - reg_rcr &= (~RCR_CBSSID); - rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, - (u8 *)(®_rcr)); - _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4)|BIT(5)), 0); + reg_rcr &= ~RCR_CBSSID; + tmp = BIT(4) | BIT(5); } + reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); + rtlpriv->cfg->ops->set_hw_reg(hw, + HW_VAR_RCR, (u8 *) (®_rcr)); + _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0); } } +/*========================================================================== */ + int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) { + struct rtl_priv *rtlpriv = rtl_priv(hw); + if (_rtl92cu_set_media_status(hw, type)) return -EOPNOTSUPP; - _rtl92cu_set_check_bssid(hw, type); + + if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { + if (type != NL80211_IFTYPE_AP) + rtl92cu_set_check_bssid(hw, true); + } else { + rtl92cu_set_check_bssid(hw, false); + } + return 0; } -- cgit v1.2.3 From bf4d7be57ba9040347065f48a60f895a254f6e28 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Wed, 13 Mar 2013 17:13:46 +0530 Subject: pinctrl: generic: Fix compilation error The function definition of pinconf_generic_dump_config is defined under CONFIG_DEBUG_FS macro. Define the declaration too under this macro. Without this patch we get the following build error: drivers/built-in.o: In function `pcs_pinconf_config_dbg_show': drivers/pinctrl/pinctrl-single.c:726: undefined reference to `pinconf_generic_dump_config' Signed-off-by: Sachin Kamat Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index e3ed8cb072a5..bfda73d64eed 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -90,7 +90,7 @@ static inline void pinconf_init_device_debugfs(struct dentry *devroot, * pin config. */ -#ifdef CONFIG_GENERIC_PINCONF +#if defined(CONFIG_GENERIC_PINCONF) && defined(CONFIG_DEBUG_FS) void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev, struct seq_file *s, unsigned pin); -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 27b351c5546008c640b3e65152f60ca74b3706f1 Mon Sep 17 00:00:00 2001 From: Bill Pemberton Date: Wed, 13 Mar 2013 09:50:15 -0400 Subject: USB: quatech2: only write to the tty if the port is open. The commit 2e124b4a390ca85325fae75764bef92f0547fa25 removed the checks that prevented qt2_process_read_urb() from trying to put chars into ttys that weren't actually opened. This resulted in 'tty is NULL' warnings from flush_to_ldisc() when the device was used. The devices use just one read urb for all ports. As a result qt2_process_read_urb() may be called with the current port set to a port number that has not been opened. Add a check if the port is open before calling tty_flip_buffer_push(). Signed-off-by: Bill Pemberton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/quatech2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 00e6c9bac8a3..d643a4d4d770 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -661,7 +661,9 @@ void qt2_process_read_urb(struct urb *urb) __func__); break; } - tty_flip_buffer_push(&port->port); + + if (port_priv->is_open) + tty_flip_buffer_push(&port->port); newport = *(ch + 3); @@ -704,7 +706,8 @@ void qt2_process_read_urb(struct urb *urb) tty_insert_flip_string(&port->port, ch, 1); } - tty_flip_buffer_push(&port->port); + if (port_priv->is_open) + tty_flip_buffer_push(&port->port); } static void qt2_write_bulk_callback(struct urb *urb) -- cgit v1.2.3 From 2563a4524febe8f4a98e717e02436d1aaf672aa2 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 11 Mar 2013 12:25:19 -0700 Subject: drm/i915: restrict kernel address leak in debugfs Masks kernel address info-leak in object dumps with the %pK suffix, so they cannot be used to target kernel memory corruption attacks if the kptr_restrict sysctl is set. Signed-off-by: Kees Cook Cc: stable@vger.kernel.org Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index aae31489c893..7299ea45dd03 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -103,7 +103,7 @@ static const char *cache_level_str(int type) static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { - seq_printf(m, "%p: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s", + seq_printf(m, "%pK: %s%s %8zdKiB %02x %02x %d %d %d%s%s%s", &obj->base, get_pin_flag(obj), get_tiling_flag(obj), -- cgit v1.2.3 From 3118a4f652c7b12c752f3222af0447008f9b2368 Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Mon, 11 Mar 2013 17:31:45 -0700 Subject: drm/i915: bounds check execbuffer relocation count It is possible to wrap the counter used to allocate the buffer for relocation copies. This could lead to heap writing overflows. CVE-2013-0913 v3: collapse test, improve comment v2: move check into validate_exec_list Signed-off-by: Kees Cook Reported-by: Pinkie Pie Cc: stable@vger.kernel.org Reviewed-by: Chris Wilson Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 2f2daebd0eef..3b11ab0fbc96 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -732,6 +732,8 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, int count) { int i; + int relocs_total = 0; + int relocs_max = INT_MAX / sizeof(struct drm_i915_gem_relocation_entry); for (i = 0; i < count; i++) { char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; @@ -740,10 +742,13 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, if (exec[i].flags & __EXEC_OBJECT_UNKNOWN_FLAGS) return -EINVAL; - /* First check for malicious input causing overflow */ - if (exec[i].relocation_count > - INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) + /* First check for malicious input causing overflow in + * the worst case where we need to allocate the entire + * relocation tree as a single array. + */ + if (exec[i].relocation_count > relocs_max - relocs_total) return -EINVAL; + relocs_total += exec[i].relocation_count; length = exec[i].relocation_count * sizeof(struct drm_i915_gem_relocation_entry); -- cgit v1.2.3 From 95e1b7145ed220a2124f9566ad97f4ccecdba063 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 13 Mar 2013 14:59:39 -0700 Subject: mlx4: remove leftover idr_pre_get() call Commit 6a9200603d76 ("IB/mlx4: convert to idr_alloc()") forgot to remove idr_pre_get() call in mlx4_ib_cm_paravirt_init(). It's unnecessary and idr_pre_get() will soon be deprecated. Remove it. Signed-off-by: Tejun Heo Cc: Jack Morgenstein Cc: Or Gerlitz Cc: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/infiniband/hw/mlx4/cm.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/cm.c b/drivers/infiniband/hw/mlx4/cm.c index e0d79b2395e4..add98d01476c 100644 --- a/drivers/infiniband/hw/mlx4/cm.c +++ b/drivers/infiniband/hw/mlx4/cm.c @@ -362,7 +362,6 @@ void mlx4_ib_cm_paravirt_init(struct mlx4_ib_dev *dev) INIT_LIST_HEAD(&dev->sriov.cm_list); dev->sriov.sl_id_map = RB_ROOT; idr_init(&dev->sriov.pv_id_table); - idr_pre_get(&dev->sriov.pv_id_table, GFP_KERNEL); } /* slave = -1 ==> all slaves */ -- cgit v1.2.3 From a37c3010002322f40fe668162a237aa99aac42d1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 13 Mar 2013 14:59:40 -0700 Subject: zcache: convert to idr_alloc() idr_get_new*() and friends are about to be deprecated. Convert to the new idr_alloc() interface. Only compile tested. Signed-off-by: Tejun Heo Cc: Dan Magenheimer Acked-by: Greg Kroah-Hartman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/zcache/ramster/tcp.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/ramster/tcp.c b/drivers/staging/zcache/ramster/tcp.c index aa2a1a763aa4..f6e1e5209d88 100644 --- a/drivers/staging/zcache/ramster/tcp.c +++ b/drivers/staging/zcache/ramster/tcp.c @@ -300,27 +300,22 @@ static u8 r2net_num_from_nn(struct r2net_node *nn) static int r2net_prep_nsw(struct r2net_node *nn, struct r2net_status_wait *nsw) { - int ret = 0; + int ret; - do { - if (!idr_pre_get(&nn->nn_status_idr, GFP_ATOMIC)) { - ret = -EAGAIN; - break; - } - spin_lock(&nn->nn_lock); - ret = idr_get_new(&nn->nn_status_idr, nsw, &nsw->ns_id); - if (ret == 0) - list_add_tail(&nsw->ns_node_item, - &nn->nn_status_list); - spin_unlock(&nn->nn_lock); - } while (ret == -EAGAIN); + spin_lock(&nn->nn_lock); + ret = idr_alloc(&nn->nn_status_idr, nsw, 0, 0, GFP_ATOMIC); + if (ret >= 0) { + nsw->ns_id = ret; + list_add_tail(&nsw->ns_node_item, &nn->nn_status_list); + } + spin_unlock(&nn->nn_lock); - if (ret == 0) { + if (ret >= 0) { init_waitqueue_head(&nsw->ns_wq); nsw->ns_sys_status = R2NET_ERR_NONE; nsw->ns_status = 0; + return 0; } - return ret; } -- cgit v1.2.3 From 8e467e855ca5ed2921f290655f96ac40d5dc571c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 13 Mar 2013 14:59:41 -0700 Subject: tidspbridge: convert to idr_alloc() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit idr_get_new*() and friends are about to be deprecated. Convert to the new idr_alloc() interface. There are some peculiarities and possible bugs in the converted functions. This patch preserves those. * drv_insert_node_res_element() returns -ENOMEM on alloc failure, -EFAULT if id space is exhausted. -EFAULT is at best misleading. * drv_proc_insert_strm_res_element() is even weirder. It returns -EFAULT if kzalloc() fails, -ENOMEM if idr preloading fails and -EPERM if id space is exhausted. What's going on here? * drv_proc_insert_strm_res_element() doesn't free *pstrm_res after failure. Only compile tested. Signed-off-by: Tejun Heo Acked-by: Greg Kroah-Hartman Cc: Víctor Manuel Jáquez Leal Cc: Rene Sapiens Cc: Armando Uribe Cc: Omar Ramirez Luna Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/staging/tidspbridge/rmgr/drv.c | 70 +++++++++++++--------------------- 1 file changed, 26 insertions(+), 44 deletions(-) (limited to 'drivers') diff --git a/drivers/staging/tidspbridge/rmgr/drv.c b/drivers/staging/tidspbridge/rmgr/drv.c index db1da28cecba..be26917a6896 100644 --- a/drivers/staging/tidspbridge/rmgr/drv.c +++ b/drivers/staging/tidspbridge/rmgr/drv.c @@ -76,37 +76,28 @@ int drv_insert_node_res_element(void *hnode, void *node_resource, struct node_res_object **node_res_obj = (struct node_res_object **)node_resource; struct process_context *ctxt = (struct process_context *)process_ctxt; - int status = 0; int retval; *node_res_obj = kzalloc(sizeof(struct node_res_object), GFP_KERNEL); - if (!*node_res_obj) { - status = -ENOMEM; - goto func_end; - } + if (!*node_res_obj) + return -ENOMEM; (*node_res_obj)->node = hnode; - retval = idr_get_new(ctxt->node_id, *node_res_obj, - &(*node_res_obj)->id); - if (retval == -EAGAIN) { - if (!idr_pre_get(ctxt->node_id, GFP_KERNEL)) { - pr_err("%s: OUT OF MEMORY\n", __func__); - status = -ENOMEM; - goto func_end; - } - - retval = idr_get_new(ctxt->node_id, *node_res_obj, - &(*node_res_obj)->id); + retval = idr_alloc(ctxt->node_id, *node_res_obj, 0, 0, GFP_KERNEL); + if (retval >= 0) { + (*node_res_obj)->id = retval; + return 0; } - if (retval) { + + kfree(*node_res_obj); + + if (retval == -ENOSPC) { pr_err("%s: FAILED, IDR is FULL\n", __func__); - status = -EFAULT; + return -EFAULT; + } else { + pr_err("%s: OUT OF MEMORY\n", __func__); + return -ENOMEM; } -func_end: - if (status) - kfree(*node_res_obj); - - return status; } /* Release all Node resources and its context @@ -201,35 +192,26 @@ int drv_proc_insert_strm_res_element(void *stream_obj, struct strm_res_object **pstrm_res = (struct strm_res_object **)strm_res; struct process_context *ctxt = (struct process_context *)process_ctxt; - int status = 0; int retval; *pstrm_res = kzalloc(sizeof(struct strm_res_object), GFP_KERNEL); - if (*pstrm_res == NULL) { - status = -EFAULT; - goto func_end; - } + if (*pstrm_res == NULL) + return -EFAULT; (*pstrm_res)->stream = stream_obj; - retval = idr_get_new(ctxt->stream_id, *pstrm_res, - &(*pstrm_res)->id); - if (retval == -EAGAIN) { - if (!idr_pre_get(ctxt->stream_id, GFP_KERNEL)) { - pr_err("%s: OUT OF MEMORY\n", __func__); - status = -ENOMEM; - goto func_end; - } - - retval = idr_get_new(ctxt->stream_id, *pstrm_res, - &(*pstrm_res)->id); + retval = idr_alloc(ctxt->stream_id, *pstrm_res, 0, 0, GFP_KERNEL); + if (retval >= 0) { + (*pstrm_res)->id = retval; + return 0; } - if (retval) { + + if (retval == -ENOSPC) { pr_err("%s: FAILED, IDR is FULL\n", __func__); - status = -EPERM; + return -EPERM; + } else { + pr_err("%s: OUT OF MEMORY\n", __func__); + return -ENOMEM; } - -func_end: - return status; } static int drv_proc_free_strm_res(int id, void *p, void *process_ctxt) -- cgit v1.2.3 From 647f8d94a4e69d39e88a617846755655853c20f5 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Fri, 8 Mar 2013 16:18:21 +0100 Subject: ARM: at91: add gpio suspend/resume support when using pinctrl gpio suspend/resume and wakeup sources where not managed when using pinctrl so it was impossible to wake up the system with a gpio. Signed-off-by: Ludovic Desroches Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Linus Walleij Signed-off-by: Nicolas Ferre --- arch/arm/mach-at91/include/mach/gpio.h | 8 +++++ arch/arm/mach-at91/pm.c | 10 ++++-- drivers/pinctrl/pinctrl-at91.c | 61 +++++++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index eed465ab0dd7..5fc23771c154 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -209,6 +209,14 @@ extern int at91_get_gpio_value(unsigned pin); extern void at91_gpio_suspend(void); extern void at91_gpio_resume(void); +#ifdef CONFIG_PINCTRL_AT91 +extern void at91_pinctrl_gpio_suspend(void); +extern void at91_pinctrl_gpio_resume(void); +#else +static inline void at91_pinctrl_gpio_suspend(void) {} +static inline void at91_pinctrl_gpio_resume(void) {} +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index adb6db888a1f..73f1f250403a 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -201,7 +201,10 @@ extern u32 at91_slow_clock_sz; static int at91_pm_enter(suspend_state_t state) { - at91_gpio_suspend(); + if (of_have_populated_dt()) + at91_pinctrl_gpio_suspend(); + else + at91_gpio_suspend(); at91_irq_suspend(); pr_debug("AT91: PM - wake mask %08x, pm state %d\n", @@ -286,7 +289,10 @@ static int at91_pm_enter(suspend_state_t state) error: target_state = PM_SUSPEND_ON; at91_irq_resume(); - at91_gpio_resume(); + if (of_have_populated_dt()) + at91_pinctrl_gpio_resume(); + else + at91_gpio_resume(); return 0; } diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 75933a6aa828..efb7f10e902a 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -1277,21 +1277,80 @@ static int alt_gpio_irq_type(struct irq_data *d, unsigned type) } #ifdef CONFIG_PM + +static u32 wakeups[MAX_GPIO_BANKS]; +static u32 backups[MAX_GPIO_BANKS]; + static int gpio_irq_set_wake(struct irq_data *d, unsigned state) { struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(d); unsigned bank = at91_gpio->pioc_idx; + unsigned mask = 1 << d->hwirq; if (unlikely(bank >= MAX_GPIO_BANKS)) return -EINVAL; + if (state) + wakeups[bank] |= mask; + else + wakeups[bank] &= ~mask; + irq_set_irq_wake(at91_gpio->pioc_virq, state); return 0; } + +void at91_pinctrl_gpio_suspend(void) +{ + int i; + + for (i = 0; i < gpio_banks; i++) { + void __iomem *pio; + + if (!gpio_chips[i]) + continue; + + pio = gpio_chips[i]->regbase; + + backups[i] = __raw_readl(pio + PIO_IMR); + __raw_writel(backups[i], pio + PIO_IDR); + __raw_writel(wakeups[i], pio + PIO_IER); + + if (!wakeups[i]) { + clk_unprepare(gpio_chips[i]->clock); + clk_disable(gpio_chips[i]->clock); + } else { + printk(KERN_DEBUG "GPIO-%c may wake for %08x\n", + 'A'+i, wakeups[i]); + } + } +} + +void at91_pinctrl_gpio_resume(void) +{ + int i; + + for (i = 0; i < gpio_banks; i++) { + void __iomem *pio; + + if (!gpio_chips[i]) + continue; + + pio = gpio_chips[i]->regbase; + + if (!wakeups[i]) { + if (clk_prepare(gpio_chips[i]->clock) == 0) + clk_enable(gpio_chips[i]->clock); + } + + __raw_writel(wakeups[i], pio + PIO_IDR); + __raw_writel(backups[i], pio + PIO_IER); + } +} + #else #define gpio_irq_set_wake NULL -#endif +#endif /* CONFIG_PM */ static struct irq_chip gpio_irqchip = { .name = "GPIO", -- cgit v1.2.3 From db9e51617faad3a54d10b7cb340a82688ec0232d Mon Sep 17 00:00:00 2001 From: Mikhail Kshevetskiy Date: Thu, 14 Mar 2013 10:18:29 +0100 Subject: usb: musb: da8xx: Fix build breakage due to typo Commit 032ec49f5351e9cb242b1a1c367d14415043ab95 (usb: musb: drop useless board_mode usage) introduced a typo that breaks the build. Signed-off-by: Mikhail Kshevetskiy [ Fixed commit message ] Cc: Mikhail Kshevetskiy Cc: Sergei Shtylyov Cc: Greg Kroah-Hartman Cc: stable@vger.kernel.org Signed-off-by: Michael Riesch Signed-off-by: Felipe Balbi --- drivers/usb/musb/da8xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/musb/da8xx.c b/drivers/usb/musb/da8xx.c index 7c71769d71ff..41613a2b35e8 100644 --- a/drivers/usb/musb/da8xx.c +++ b/drivers/usb/musb/da8xx.c @@ -327,7 +327,7 @@ static irqreturn_t da8xx_musb_interrupt(int irq, void *hci) u8 devctl = musb_readb(mregs, MUSB_DEVCTL); int err; - err = musb->int_usb & USB_INTR_VBUSERROR; + err = musb->int_usb & MUSB_INTR_VBUSERROR; if (err) { /* * The Mentor core doesn't debounce VBUS as needed -- cgit v1.2.3 From 273daf2f2ab9f42d82f017b20fcf902ec8d7cffa Mon Sep 17 00:00:00 2001 From: Bo Shen Date: Wed, 13 Mar 2013 16:54:07 +0800 Subject: usb: gadget: u_serial: fix typo which cause build warning fix typo error introduced by commit ea0e6276 (usb: gadget: add multiple definition guards) which causes the following build warning: warning: "pr_vdebug" redefined Signed-off-by: Bo Shen Signed-off-by: Felipe Balbi --- drivers/usb/gadget/u_serial.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index c5034d9c946b..b369292d4b90 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c @@ -136,7 +136,7 @@ static struct portmaster { pr_debug(fmt, ##arg) #endif /* pr_vdebug */ #else -#ifndef pr_vdebig +#ifndef pr_vdebug #define pr_vdebug(fmt, arg...) \ ({ if (0) pr_debug(fmt, ##arg); }) #endif /* pr_vdebug */ -- cgit v1.2.3 From 5bc7c33ca93a285dcfe7b7fd64970f6314440ad1 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Wed, 13 Mar 2013 09:51:31 -0700 Subject: mtd: nand: reintroduce NAND_NO_READRDY as NAND_NEED_READRDY This partially reverts commit 1696e6bc2ae83734e64e206ac99766ea19e9a14e ("mtd: nand: kill NAND_NO_READRDY"). In that patch I overlooked a few things. The original documentation for NAND_NO_READRDY included "True for all large page devices, as they do not support autoincrement." I was conflating "not support autoincrement" with the NAND_NO_AUTOINCR option, which was in fact doing nothing. So, when I dropped NAND_NO_AUTOINCR, I concluded that I then could harmlessly drop NAND_NO_READRDY. But of course the fact the NAND_NO_AUTOINCR was doing nothing didn't mean NAND_NO_READRDY was doing nothing... So, NAND_NO_READRDY is re-introduced as NAND_NEED_READRDY and applied only to those few remaining small-page NAND which needed it in the first place. Cc: stable@kernel.org [3.5+] Reported-by: Alexander Shiyan Tested-by: Alexander Shiyan Signed-off-by: Brian Norris Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 16 +++++++++ drivers/mtd/nand/nand_ids.c | 80 +++++++++++++++++++++++--------------------- include/linux/mtd/nand.h | 7 ++++ 3 files changed, 64 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 43214151b882..42c63927609d 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1523,6 +1523,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, oobreadlen -= toread; } } + + if (chip->options & NAND_NEED_READRDY) { + /* Apply delay or wait for ready/busy pin */ + if (!chip->dev_ready) + udelay(chip->chip_delay); + else + nand_wait_ready(mtd); + } } else { memcpy(buf, chip->buffers->databuf + col, bytes); buf += bytes; @@ -1787,6 +1795,14 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, len = min(len, readlen); buf = nand_transfer_oob(chip, buf, ops, len); + if (chip->options & NAND_NEED_READRDY) { + /* Apply delay or wait for ready/busy pin */ + if (!chip->dev_ready) + udelay(chip->chip_delay); + else + nand_wait_ready(mtd); + } + readlen -= len; if (!readlen) break; diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index e3aa2748a6e7..9c612388e5de 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c @@ -22,49 +22,51 @@ * 512 512 Byte page size */ struct nand_flash_dev nand_flash_ids[] = { +#define SP_OPTIONS NAND_NEED_READRDY +#define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16) #ifdef CONFIG_MTD_NAND_MUSEUM_IDS - {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, - {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, - {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, - {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, - {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, - {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, - {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, - {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, - {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, - {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, - - {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, - {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, - {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, - {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, + {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, SP_OPTIONS}, + {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, SP_OPTIONS}, + {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, SP_OPTIONS}, + {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, SP_OPTIONS}, + {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, SP_OPTIONS}, + {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, SP_OPTIONS}, + {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, SP_OPTIONS}, + {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, SP_OPTIONS}, + {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, SP_OPTIONS}, + {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, SP_OPTIONS}, + + {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, SP_OPTIONS}, + {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, SP_OPTIONS}, + {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, SP_OPTIONS16}, + {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, SP_OPTIONS16}, #endif - {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, - {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, - {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, - {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, - - {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, - {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, - {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, - {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, - - {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, - {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, - {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, - {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, - - {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, - {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, - {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, - {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, - {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, - {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, - {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, - - {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, + {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, SP_OPTIONS}, + {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, SP_OPTIONS}, + {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, SP_OPTIONS16}, + {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, SP_OPTIONS16}, + + {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, SP_OPTIONS}, + {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, SP_OPTIONS}, + {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, SP_OPTIONS16}, + {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, SP_OPTIONS16}, + + {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, SP_OPTIONS}, + {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, SP_OPTIONS}, + {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, SP_OPTIONS16}, + {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, SP_OPTIONS16}, + + {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, SP_OPTIONS}, + {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, SP_OPTIONS}, + {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, SP_OPTIONS}, + {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, SP_OPTIONS16}, + {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, SP_OPTIONS16}, + {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, SP_OPTIONS16}, + {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, SP_OPTIONS16}, + + {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, SP_OPTIONS}, /* * These are the new chips with large page size. The pagesize and the diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 7ccb3c59ed60..ef52d9c91459 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -187,6 +187,13 @@ typedef enum { * This happens with the Renesas AG-AND chips, possibly others. */ #define BBT_AUTO_REFRESH 0x00000080 +/* + * Chip requires ready check on read (for auto-incremented sequential read). + * True only for small page devices; large page devices do not support + * autoincrement. + */ +#define NAND_NEED_READRDY 0x00000100 + /* Chip does not allow subpage writes */ #define NAND_NO_SUBPAGE_WRITE 0x00000200 -- cgit v1.2.3 From df069079c153d22adf6c28dcc0b1cf62bba75167 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 14 Mar 2013 16:27:18 +0800 Subject: hwmon: (lineage-pem) Add missing terminating entry for pem_[input|fan]_attributes Signed-off-by: Axel Lin Cc: stable@vger.kernel.org Acked-by: Jean Delvare Signed-off-by: Guenter Roeck --- drivers/hwmon/lineage-pem.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/lineage-pem.c b/drivers/hwmon/lineage-pem.c index 41df29f59b0e..ebbb9f4f27a3 100644 --- a/drivers/hwmon/lineage-pem.c +++ b/drivers/hwmon/lineage-pem.c @@ -422,6 +422,7 @@ static struct attribute *pem_input_attributes[] = { &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_curr1_input.dev_attr.attr, &sensor_dev_attr_power1_input.dev_attr.attr, + NULL }; static const struct attribute_group pem_input_group = { @@ -432,6 +433,7 @@ static struct attribute *pem_fan_attributes[] = { &sensor_dev_attr_fan1_input.dev_attr.attr, &sensor_dev_attr_fan2_input.dev_attr.attr, &sensor_dev_attr_fan3_input.dev_attr.attr, + NULL }; static const struct attribute_group pem_fan_group = { -- cgit v1.2.3 From 6975404fb9bcc3ca41946ce0506f97db30fb8705 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 14 Mar 2013 13:30:20 +0000 Subject: hwmon: (pmbus) Fix krealloc() misuse in pmbus_add_attribute() 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 Signed-off-by: Guenter Roeck --- drivers/hwmon/pmbus/pmbus_core.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c index 80eef50c50fd..9add60920ac0 100644 --- a/drivers/hwmon/pmbus/pmbus_core.c +++ b/drivers/hwmon/pmbus/pmbus_core.c @@ -766,12 +766,14 @@ static ssize_t pmbus_show_label(struct device *dev, static int pmbus_add_attribute(struct pmbus_data *data, struct attribute *attr) { if (data->num_attributes >= data->max_attributes - 1) { - data->max_attributes += PMBUS_ATTR_ALLOC_SIZE; - data->group.attrs = krealloc(data->group.attrs, - sizeof(struct attribute *) * - data->max_attributes, GFP_KERNEL); - if (data->group.attrs == NULL) + int new_max_attrs = data->max_attributes + PMBUS_ATTR_ALLOC_SIZE; + void *new_attrs = krealloc(data->group.attrs, + new_max_attrs * sizeof(void *), + GFP_KERNEL); + if (!new_attrs) return -ENOMEM; + data->group.attrs = new_attrs; + data->max_attributes = new_max_attrs; } data->group.attrs[data->num_attributes++] = attr; -- cgit v1.2.3 From 8c958c703ef8804093437959221951eaf0e1e664 Mon Sep 17 00:00:00 2001 From: Guenter Roeck Date: Thu, 21 Feb 2013 10:27:54 -0800 Subject: hwmon: (pmbus/ltc2978) Fix temperature reporting On LTC2978, only READ_TEMPERATURE is supported. It reports the internal junction temperature. This register is unpaged. On LTC3880, READ_TEMPERATURE and READ_TEMPERATURE2 are supported. READ_TEMPERATURE is paged and reports external temperatures. READ_TEMPERATURE2 is unpaged and reports the internal junction temperature. Signed-off-by: Guenter Roeck Cc: stable@vger.kernel.org # 3.2+ Acked-by: Jean Delvare --- drivers/hwmon/pmbus/ltc2978.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/pmbus/ltc2978.c b/drivers/hwmon/pmbus/ltc2978.c index a58de38e23d8..6d6130752f94 100644 --- a/drivers/hwmon/pmbus/ltc2978.c +++ b/drivers/hwmon/pmbus/ltc2978.c @@ -59,7 +59,7 @@ enum chips { ltc2978, ltc3880 }; struct ltc2978_data { enum chips id; int vin_min, vin_max; - int temp_min, temp_max; + int temp_min, temp_max[2]; int vout_min[8], vout_max[8]; int iout_max[2]; int temp2_max; @@ -113,9 +113,10 @@ static int ltc2978_read_word_data_common(struct i2c_client *client, int page, ret = pmbus_read_word_data(client, page, LTC2978_MFR_TEMPERATURE_PEAK); if (ret >= 0) { - if (lin11_to_val(ret) > lin11_to_val(data->temp_max)) - data->temp_max = ret; - ret = data->temp_max; + if (lin11_to_val(ret) + > lin11_to_val(data->temp_max[page])) + data->temp_max[page] = ret; + ret = data->temp_max[page]; } break; case PMBUS_VIRT_RESET_VOUT_HISTORY: @@ -266,7 +267,7 @@ static int ltc2978_write_word_data(struct i2c_client *client, int page, break; case PMBUS_VIRT_RESET_TEMP_HISTORY: data->temp_min = 0x7bff; - data->temp_max = 0x7c00; + data->temp_max[page] = 0x7c00; ret = ltc2978_clear_peaks(client, page, data->id); break; default: @@ -323,7 +324,8 @@ static int ltc2978_probe(struct i2c_client *client, data->vin_min = 0x7bff; data->vin_max = 0x7c00; data->temp_min = 0x7bff; - data->temp_max = 0x7c00; + for (i = 0; i < ARRAY_SIZE(data->temp_max); i++) + data->temp_max[i] = 0x7c00; data->temp2_max = 0x7c00; switch (data->id) { -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From d6d1053a8bbf75e5eb6ef29ddcf87e66421763c4 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 1 Mar 2013 14:12:01 +0100 Subject: clk: vt8500: Fix "fix device clock divisor calculations" Patch 72480014b8 "Fix device clock divisor calculations" was apparently rebased incorrectly before it got upstream, causing a build error. Replacing the "prate" pointer with the local parent_rate is most likely the correct solution. Signed-off-by: Arnd Bergmann Cc: Tony Prisk Cc: Mike Turquette --- drivers/clk/clk-vt8500.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/clk-vt8500.c b/drivers/clk/clk-vt8500.c index b5538bba7a10..09c63315e579 100644 --- a/drivers/clk/clk-vt8500.c +++ b/drivers/clk/clk-vt8500.c @@ -157,7 +157,7 @@ static int vt8500_dclk_set_rate(struct clk_hw *hw, unsigned long rate, divisor = parent_rate / rate; /* If prate / rate would be decimal, incr the divisor */ - if (rate * divisor < *prate) + if (rate * divisor < parent_rate) divisor++; if (divisor == cdev->div_mask + 1) -- cgit v1.2.3 From 6fdd496e07f511a94ba27e4a1433038b32d6af05 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 13 Feb 2013 17:11:09 +0100 Subject: input/joystick: use get_cycles on ARM ARM normally has an accurate clock source, so we can theoretically use analog joysticks more accurately and at the same time avoid the build warning #warning Precise timer not defined for this architecture. from the joystick driver. Now, why anybody would use that driver no ARM I have no idea, but Ben Dooks enabled it in the s3c2410_defconfig along with a bunch of other drivers, even though that platform has neither ISA nor PCI support. It still seems to be the right thing to fix this quirk. Signed-off-by: Arnd Bergmann Cc: Dmitry Torokhov Cc: Vojtech Pavlik Cc: Ben Dooks --- drivers/input/joystick/analog.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 7cd74e29cbc8..9135606c8649 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -158,14 +158,10 @@ static unsigned int get_time_pit(void) #define GET_TIME(x) rdtscl(x) #define DELTA(x,y) ((y)-(x)) #define TIME_NAME "TSC" -#elif defined(__alpha__) +#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_TILE) #define GET_TIME(x) do { x = get_cycles(); } while (0) #define DELTA(x,y) ((y)-(x)) -#define TIME_NAME "PCC" -#elif defined(CONFIG_MN10300) || defined(CONFIG_TILE) -#define GET_TIME(x) do { x = get_cycles(); } while (0) -#define DELTA(x, y) ((x) - (y)) -#define TIME_NAME "TSC" +#define TIME_NAME "get_cycles" #else #define FAKE_TIME static unsigned long analog_faketime = 0; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 037154105e3767324db7c34bf8f540a12cb61d70 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Mar 2013 22:56:38 +0100 Subject: mfd: twl4030-madc: Remove __exit_p annotation 4740f73fe5 "mfd: remove use of __devexit" removed the __devexit annotation on the twl4030_madc_remove function, but left an __exit_p() present on the pointer to this function. Using __exit_p was as wrong with the devexit in place as it is now, but now we get a gcc warning about an unused function. In order for the twl4030_madc_remove to work correctly in built-in code, we have to remove the __exit_p. Cc: Bill Pemberton Cc: Greg Kroah-Hartman Signed-off-by: Arnd Bergmann Signed-off-by: Samuel Ortiz --- drivers/mfd/twl4030-madc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c index 88ff9dc83305..942b666a2a07 100644 --- a/drivers/mfd/twl4030-madc.c +++ b/drivers/mfd/twl4030-madc.c @@ -800,7 +800,7 @@ static int twl4030_madc_remove(struct platform_device *pdev) static struct platform_driver twl4030_madc_driver = { .probe = twl4030_madc_probe, - .remove = __exit_p(twl4030_madc_remove), + .remove = twl4030_madc_remove, .driver = { .name = "twl4030_madc", .owner = THIS_MODULE, -- cgit v1.2.3 From d97e74976982a35168c7f131cce0d93537337a26 Mon Sep 17 00:00:00 2001 From: Lucas Stach Date: Thu, 14 Mar 2013 05:12:01 +0000 Subject: net: fec: restart the FEC when PHY speed changes Proviously we would only restart the FEC when PHY link or duplex state changed. PHY does not always bring down the link for speed changes, in which case we would not detect any change and keep FEC running. Switching link speed without restarting the FEC results in the FEC being stuck in an indefinite state, generating error conditions for every packet. Signed-off-by: Lucas Stach Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 26 +++++++++++++++----------- drivers/net/ethernet/freescale/fec.h | 1 + 2 files changed, 16 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 069a155d16ed..61d2e6202bf3 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -934,24 +934,28 @@ static void fec_enet_adjust_link(struct net_device *ndev) goto spin_unlock; } - /* Duplex link change */ if (phy_dev->link) { - if (fep->full_duplex != phy_dev->duplex) { - fec_restart(ndev, phy_dev->duplex); - /* prevent unnecessary second fec_restart() below */ + if (!fep->link) { fep->link = phy_dev->link; status_change = 1; } - } - /* Link on or off change */ - if (phy_dev->link != fep->link) { - fep->link = phy_dev->link; - if (phy_dev->link) + if (fep->full_duplex != phy_dev->duplex) + status_change = 1; + + if (phy_dev->speed != fep->speed) { + fep->speed = phy_dev->speed; + status_change = 1; + } + + /* if any of the above changed restart the FEC */ + if (status_change) fec_restart(ndev, phy_dev->duplex); - else + } else { + if (fep->link) { fec_stop(ndev); - status_change = 1; + status_change = 1; + } } spin_unlock: diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index f5390071efd0..eb4372962839 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -240,6 +240,7 @@ struct fec_enet_private { phy_interface_t phy_interface; int link; int full_duplex; + int speed; struct completion mdio_done; int irq[FEC_IRQ_NUM]; int bufdesc_ex; -- cgit v1.2.3 From 3f104c38259dcb3e5443c246f0805bc04d887cc3 Mon Sep 17 00:00:00 2001 From: Georg Hofmann Date: Thu, 14 Mar 2013 06:54:09 +0000 Subject: net: fec: fix missing napi_disable call Commit dc975382d2ef36be7e78fac3717927de1a5abcd8 introduces napi support but never calls napi_disable. This will generate a kernel oops (kernel BUG at include/linux/netdevice.h:473!) every time, when ndo_stop is called followed by ndo_start. Add the missing napi_diable call. Signed-off-by: Georg Hofmann Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 61d2e6202bf3..e3f39372ce25 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1441,6 +1441,7 @@ fec_enet_close(struct net_device *ndev) struct fec_enet_private *fep = netdev_priv(ndev); /* Don't know what to do yet. */ + napi_disable(&fep->napi); fep->opened = 0; netif_stop_queue(ndev); fec_stop(ndev); -- cgit v1.2.3 From 1e731cb986d564c4938bcba89ff5f4aea1d8e2fb Mon Sep 17 00:00:00 2001 From: Robert de Vries Date: Thu, 14 Mar 2013 09:29:06 +0000 Subject: smsc75xx: configuration help incorrectly mentions smsc95xx The Kconfig file help information incorrectly mentions that the SMSC LAN75xx config option is for SMSC LAN95xx devices. Signed-off-by: Robert de Vries Signed-off-by: David S. Miller --- drivers/net/usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 3b6e9b83342d..7c769d8e25ad 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -268,7 +268,7 @@ config USB_NET_SMSC75XX select CRC16 select CRC32 help - This option adds support for SMSC LAN95XX based USB 2.0 + This option adds support for SMSC LAN75XX based USB 2.0 Gigabit Ethernet adapters. config USB_NET_SMSC95XX -- cgit v1.2.3 From aaa0c23cb90141309f5076ba5e3bfbd39544b985 Mon Sep 17 00:00:00 2001 From: Zhouyi Zhou Date: Thu, 14 Mar 2013 17:21:50 +0000 Subject: Fix dst_neigh_lookup/dst_neigh_lookup_skb return value handling bug When neighbour table is full, dst_neigh_lookup/dst_neigh_lookup_skb will return -ENOBUFS which is absolutely non zero, while all the code in kernel which use above functions assume failure only on zero return which will cause panic. (for example: : https://bugzilla.kernel.org/show_bug.cgi?id=54731). This patch corrects above error with smallest changes to kernel source code and also correct two return value check missing bugs in drivers/infiniband/hw/cxgb4/cm.c Tested on my x86_64 SMP machine Reported-by: Zhouyi Zhou Tested-by: Zhouyi Zhou Signed-off-by: Zhouyi Zhou Signed-off-by: David S. Miller --- drivers/infiniband/hw/cxgb4/cm.c | 12 ++++++++++++ include/net/dst.h | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c index 565bfb161c1a..a3fde52840ca 100644 --- a/drivers/infiniband/hw/cxgb4/cm.c +++ b/drivers/infiniband/hw/cxgb4/cm.c @@ -1575,6 +1575,12 @@ static int c4iw_reconnect(struct c4iw_ep *ep) neigh = dst_neigh_lookup(ep->dst, &ep->com.cm_id->remote_addr.sin_addr.s_addr); + if (!neigh) { + pr_err("%s - cannot alloc neigh.\n", __func__); + err = -ENOMEM; + goto fail4; + } + /* get a l2t entry */ if (neigh->dev->flags & IFF_LOOPBACK) { PDBG("%s LOOPBACK\n", __func__); @@ -3053,6 +3059,12 @@ static int rx_pkt(struct c4iw_dev *dev, struct sk_buff *skb) dst = &rt->dst; neigh = dst_neigh_lookup_skb(dst, skb); + if (!neigh) { + pr_err("%s - failed to allocate neigh!\n", + __func__); + goto free_dst; + } + if (neigh->dev->flags & IFF_LOOPBACK) { pdev = ip_dev_find(&init_net, iph->daddr); e = cxgb4_l2t_get(dev->rdev.lldi.l2t, neigh, diff --git a/include/net/dst.h b/include/net/dst.h index 853cda11e518..1f8fd109e225 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -413,13 +413,15 @@ static inline int dst_neigh_output(struct dst_entry *dst, struct neighbour *n, static inline struct neighbour *dst_neigh_lookup(const struct dst_entry *dst, const void *daddr) { - return dst->ops->neigh_lookup(dst, NULL, daddr); + struct neighbour *n = dst->ops->neigh_lookup(dst, NULL, daddr); + return IS_ERR(n) ? NULL : n; } static inline struct neighbour *dst_neigh_lookup_skb(const struct dst_entry *dst, struct sk_buff *skb) { - return dst->ops->neigh_lookup(dst, skb, NULL); + struct neighbour *n = dst->ops->neigh_lookup(dst, skb, NULL); + return IS_ERR(n) ? NULL : n; } static inline void dst_link_failure(struct sk_buff *skb) -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From d66629c1325399cf080ba8b2fb086c10e5439cdd Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Fri, 15 Mar 2013 11:00:39 +0800 Subject: Bluetooth: Add support for Dell[QCA 0cf3:0036] Add support for the AR9462 chip T: Bus=03 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 3 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=0036 Rev= 0.02 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=01 I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Cc: Cc: Gustavo Padovan Signed-off-by: Ming Lei Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 3095d2e74f24..0a6ef6b694d4 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -73,6 +73,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x03F0, 0x311D) }, /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x0036) }, { USB_DEVICE(0x0CF3, 0x3004) }, { USB_DEVICE(0x0CF3, 0x3008) }, { USB_DEVICE(0x0CF3, 0x311D) }, @@ -107,6 +108,7 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); static struct usb_device_id ath3k_blist_tbl[] = { /* Atheros AR3012 with sflash firmware*/ + { USB_DEVICE(0x0CF3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index e547851870e7..11ac3036bb8a 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -131,6 +131,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x03f0, 0x311d), .driver_info = BTUSB_IGNORE }, /* Atheros 3012 with sflash firmware */ + { USB_DEVICE(0x0cf3, 0x0036), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, -- cgit v1.2.3 From 2c36af0e559c0a0674ad846527116df41aa5f612 Mon Sep 17 00:00:00 2001 From: Hiroshi Doyu Date: Fri, 15 Mar 2013 07:54:11 +0100 Subject: ARM: 7675/1: amba: tegra-ahb: Fix build error w/ PM_SLEEP w/o PM_RUNTIME Make this depend on CONFIG_PM. This protection is necessary to not cause any build errors with any combination of PM features especially when supporting a new SoC where each PM features are being enabled one-by-one during its depelopment. Signed-off-by: Hiroshi Doyu Signed-off-by: Russell King --- drivers/amba/tegra-ahb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/amba/tegra-ahb.c b/drivers/amba/tegra-ahb.c index 093c43554963..1f44e56cc65d 100644 --- a/drivers/amba/tegra-ahb.c +++ b/drivers/amba/tegra-ahb.c @@ -158,7 +158,7 @@ int tegra_ahb_enable_smmu(struct device_node *dn) EXPORT_SYMBOL(tegra_ahb_enable_smmu); #endif -#ifdef CONFIG_PM_SLEEP +#ifdef CONFIG_PM static int tegra_ahb_suspend(struct device *dev) { int i; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 7cb035d9e619a8d20f5d3b9791f8cb5160d19e70 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 10 Mar 2013 13:56:08 +0200 Subject: mei: add mei_stop function to stop mei device mei_stop calls mei_reset with disabling the interrupts. It will have the same effect as the open code it replaces in the mei_remove. The reset sequence on remove is required for the Lynx Point LP devices to clean the reset state. mei_stop is called from mei_pci_suspend and mei_remove functions Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/init.c | 18 ++++++++++++++++ drivers/misc/mei/mei_dev.h | 1 + drivers/misc/mei/pci-me.c | 52 +++++++--------------------------------------- 3 files changed, 26 insertions(+), 45 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/init.c b/drivers/misc/mei/init.c index 6ec530168afb..356179991a2e 100644 --- a/drivers/misc/mei/init.c +++ b/drivers/misc/mei/init.c @@ -183,6 +183,24 @@ void mei_reset(struct mei_device *dev, int interrupts_enabled) mei_cl_all_write_clear(dev); } +void mei_stop(struct mei_device *dev) +{ + dev_dbg(&dev->pdev->dev, "stopping the device.\n"); + + mutex_lock(&dev->device_lock); + + cancel_delayed_work(&dev->timer_work); + + mei_wd_stop(dev); + + dev->dev_state = MEI_DEV_POWER_DOWN; + mei_reset(dev, 0); + + mutex_unlock(&dev->device_lock); + + flush_scheduled_work(); +} + diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h index cb80166161f0..97873812e33b 100644 --- a/drivers/misc/mei/mei_dev.h +++ b/drivers/misc/mei/mei_dev.h @@ -381,6 +381,7 @@ static inline unsigned long mei_secs_to_jiffies(unsigned long sec) void mei_device_init(struct mei_device *dev); void mei_reset(struct mei_device *dev, int interrupts); int mei_hw_init(struct mei_device *dev); +void mei_stop(struct mei_device *dev); /* * MEI interrupt functions prototype diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c index b40ec0601ab0..b8b5c9c3ad03 100644 --- a/drivers/misc/mei/pci-me.c +++ b/drivers/misc/mei/pci-me.c @@ -247,44 +247,14 @@ static void mei_remove(struct pci_dev *pdev) hw = to_me_hw(dev); - mutex_lock(&dev->device_lock); - - cancel_delayed_work(&dev->timer_work); - mei_wd_stop(dev); + dev_err(&pdev->dev, "stop\n"); + mei_stop(dev); mei_pdev = NULL; - if (dev->iamthif_cl.state == MEI_FILE_CONNECTED) { - dev->iamthif_cl.state = MEI_FILE_DISCONNECTING; - mei_cl_disconnect(&dev->iamthif_cl); - } - if (dev->wd_cl.state == MEI_FILE_CONNECTED) { - dev->wd_cl.state = MEI_FILE_DISCONNECTING; - mei_cl_disconnect(&dev->wd_cl); - } - - /* Unregistering watchdog device */ mei_watchdog_unregister(dev); - /* remove entry if already in list */ - dev_dbg(&pdev->dev, "list del iamthif and wd file list.\n"); - - if (dev->open_handle_count > 0) - dev->open_handle_count--; - mei_cl_unlink(&dev->wd_cl); - - if (dev->open_handle_count > 0) - dev->open_handle_count--; - mei_cl_unlink(&dev->iamthif_cl); - - dev->iamthif_current_cb = NULL; - dev->me_clients_num = 0; - - mutex_unlock(&dev->device_lock); - - flush_scheduled_work(); - /* disable interrupts */ mei_disable_interrupts(dev); @@ -308,28 +278,20 @@ static int mei_pci_suspend(struct device *device) { struct pci_dev *pdev = to_pci_dev(device); struct mei_device *dev = pci_get_drvdata(pdev); - int err; if (!dev) return -ENODEV; - mutex_lock(&dev->device_lock); - cancel_delayed_work(&dev->timer_work); + dev_err(&pdev->dev, "suspend\n"); - /* Stop watchdog if exists */ - err = mei_wd_stop(dev); - /* Set new mei state */ - if (dev->dev_state == MEI_DEV_ENABLED || - dev->dev_state == MEI_DEV_RECOVERING_FROM_RESET) { - dev->dev_state = MEI_DEV_POWER_DOWN; - mei_reset(dev, 0); - } - mutex_unlock(&dev->device_lock); + mei_stop(dev); + + mei_disable_interrupts(dev); free_irq(pdev->irq, dev); pci_disable_msi(pdev); - return err; + return 0; } static int mei_pci_resume(struct device *device) -- cgit v1.2.3 From 68f8ea184bf7a552b59a38c4b0c7dc243822d2d5 Mon Sep 17 00:00:00 2001 From: Tomas Winkler Date: Sun, 10 Mar 2013 13:56:07 +0200 Subject: mei: ME hardware reset needs to be synchronized This fixes failure during initialization on Lynx Point LP devices. ME driver needs to release the device from the reset only after the FW has completed its flow and indicated it by delivering an interrupt to the host. This is the correct behavior for all the ME devices yet the the previous versions are less susceptive to the implementation that ignored FW reset completion indication. We add mei_me_hw_reset_release function which is called after reset from the interrupt thread or directly from mei_reset during power down. Signed-off-by: Tomas Winkler Signed-off-by: Greg Kroah-Hartman --- drivers/misc/mei/hw-me.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/mei/hw-me.c b/drivers/misc/mei/hw-me.c index 45ea7185c003..642c6223fa6c 100644 --- a/drivers/misc/mei/hw-me.c +++ b/drivers/misc/mei/hw-me.c @@ -151,6 +151,20 @@ static void mei_me_intr_disable(struct mei_device *dev) mei_hcsr_set(hw, hcsr); } +/** + * mei_me_hw_reset_release - release device from the reset + * + * @dev: the device structure + */ +static void mei_me_hw_reset_release(struct mei_device *dev) +{ + struct mei_me_hw *hw = to_me_hw(dev); + u32 hcsr = mei_hcsr_read(hw); + + hcsr |= H_IG; + hcsr &= ~H_RST; + mei_hcsr_set(hw, hcsr); +} /** * mei_me_hw_reset - resets fw via mei csr register. * @@ -169,18 +183,14 @@ static void mei_me_hw_reset(struct mei_device *dev, bool intr_enable) if (intr_enable) hcsr |= H_IE; else - hcsr &= ~H_IE; - - mei_hcsr_set(hw, hcsr); - - hcsr = mei_hcsr_read(hw) | H_IG; - hcsr &= ~H_RST; + hcsr |= ~H_IE; mei_hcsr_set(hw, hcsr); - hcsr = mei_hcsr_read(hw); + if (dev->dev_state == MEI_DEV_POWER_DOWN) + mei_me_hw_reset_release(dev); - dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", hcsr); + dev_dbg(&dev->pdev->dev, "current HCSR = 0x%08x.\n", mei_hcsr_read(hw)); } /** @@ -466,7 +476,8 @@ irqreturn_t mei_me_irq_thread_handler(int irq, void *dev_id) mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } else { - dev_dbg(&dev->pdev->dev, "FW not ready.\n"); + dev_dbg(&dev->pdev->dev, "Reset Completed.\n"); + mei_me_hw_reset_release(dev); mutex_unlock(&dev->device_lock); return IRQ_HANDLED; } -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 25e9789ddd9d14a8971f4a421d04f282719ab733 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 15 Mar 2013 12:58:20 -0600 Subject: vfio: include for kmalloc The vfio drivers call kmalloc or kzalloc, but do not include , which causes build errors on ARM. Signed-off-by: Arnd Bergmann Signed-off-by: Alex Williamson Cc: kvm@vger.kernel.org --- drivers/vfio/pci/vfio_pci_config.c | 1 + drivers/vfio/pci/vfio_pci_intrs.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/vfio/pci/vfio_pci_config.c b/drivers/vfio/pci/vfio_pci_config.c index 964ff22bf281..aeb00fc2d3be 100644 --- a/drivers/vfio/pci/vfio_pci_config.c +++ b/drivers/vfio/pci/vfio_pci_config.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "vfio_pci_private.h" diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c index 3639371fa697..a96509187deb 100644 --- a/drivers/vfio/pci/vfio_pci_intrs.c +++ b/drivers/vfio/pci/vfio_pci_intrs.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "vfio_pci_private.h" -- cgit v1.2.3 From 00eed9c814cb8f281be6f0f5d8f45025dc0a97eb Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Mar 2013 17:14:43 +0100 Subject: USB: xhci: correctly enable interrupts xhci has its own interrupt enabling routine, which will try to use MSI-X/MSI if present. So the usb core shouldn't try to enable legacy interrupts; on some machines the xhci legacy IRQ setting is invalid. v3: Be careful to not break XHCI_BROKEN_MSI workaround (by trenn) Cc: Bjorn Helgaas Cc: Oliver Neukum Cc: Thomas Renninger Cc: Yinghai Lu Cc: Frederik Himpe Cc: David Haerdeman Cc: Alan Stern Acked-by: Sarah Sharp Reviewed-by: Thomas Renninger Signed-off-by: Hannes Reinecke Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd-pci.c | 23 ++++++++++++++--------- drivers/usb/host/xhci.c | 3 ++- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 622b4a48e732..2b487d4797bd 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -173,6 +173,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) struct hc_driver *driver; struct usb_hcd *hcd; int retval; + int hcd_irq = 0; if (usb_disabled()) return -ENODEV; @@ -187,15 +188,19 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return -ENODEV; dev->current_state = PCI_D0; - /* The xHCI driver supports MSI and MSI-X, - * so don't fail if the BIOS doesn't provide a legacy IRQ. + /* + * The xHCI driver has its own irq management + * make sure irq setup is not touched for xhci in generic hcd code */ - if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) { - dev_err(&dev->dev, - "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", - pci_name(dev)); - retval = -ENODEV; - goto disable_pci; + if ((driver->flags & HCD_MASK) != HCD_USB3) { + if (!dev->irq) { + dev_err(&dev->dev, + "Found HC with no IRQ. Check BIOS/PCI %s setup!\n", + pci_name(dev)); + retval = -ENODEV; + goto disable_pci; + } + hcd_irq = dev->irq; } hcd = usb_create_hcd(driver, &dev->dev, pci_name(dev)); @@ -245,7 +250,7 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) pci_set_master(dev); - retval = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); + retval = usb_add_hcd(hcd, hcd_irq, IRQF_SHARED); if (retval != 0) goto unmap_registers; set_hs_companion(dev, hcd); diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index f1f01a834ba7..849470b18831 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -350,7 +350,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) * generate interrupts. Don't even try to enable MSI. */ if (xhci->quirks & XHCI_BROKEN_MSI) - return 0; + goto legacy_irq; /* unregister the legacy interrupt */ if (hcd->irq) @@ -371,6 +371,7 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd) return -EINVAL; } + legacy_irq: /* fall back to legacy interrupt*/ ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED, hcd->irq_descr, hcd); -- cgit v1.2.3 From 29f86e66428ee083aec106cca1748dc63d98ce23 Mon Sep 17 00:00:00 2001 From: Dmitry Artamonow Date: Sat, 9 Mar 2013 20:30:58 +0400 Subject: usb-storage: add unusual_devs entry for Samsung YP-Z3 mp3 player Device stucks on filesystem writes, unless following quirk is passed: echo 04e8:5136:m > /sys/module/usb_storage/parameters/quirks Add corresponding entry to unusual_devs.h Signed-off-by: Dmitry Artamonow Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index da04a074e790..1799335288bd 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -496,6 +496,13 @@ UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), +/* Added by Dmitry Artamonow */ +UNUSUAL_DEV( 0x04e8, 0x5136, 0x0000, 0x9999, + "Samsung", + "YP-Z3", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_MAX_SECTORS_64), + /* Entry and supporting patch by Theodore Kilgore . * Device uses standards-violating 32-byte Bulk Command Block Wrappers and * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. -- cgit v1.2.3 From 2a40f324541ee61c22146214349c2ce9f5c30bcf Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 15 Mar 2013 14:40:26 -0400 Subject: USB: EHCI: fix regression during bus resume This patch (as1663) fixes a regression caused by commit 6e0c3339a6f19d748f16091d0a05adeb1e1f822b (USB: EHCI: unlink one async QH at a time). In order to avoid keeping multiple QHs in an unusable intermediate state, that commit changed unlink_empty_async() so that it unlinks only one empty QH at a time. However, when the EHCI root hub is suspended, _all_ async QHs need to be unlinked. ehci_bus_suspend() used to do this by calling unlink_empty_async(), but now this only unlinks one of the QHs, not all of them. The symptom is that when the root hub is resumed, USB communications don't work for some period of time. This is because ehci-hcd doesn't realize it needs to restart the async schedule; it assumes that because some QHs are already on the schedule, the schedule must be running. The easiest way to fix the problem is add a new function that unlinks all the async QHs when the root hub is suspended. This patch should be applied to all kernels that have the 6e0c3339a6f1 commit. Signed-off-by: Alan Stern Reported-and-tested-by: Adrian Bassett Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-hcd.c | 1 + drivers/usb/host/ehci-hub.c | 2 +- drivers/usb/host/ehci-q.c | 13 +++++++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 5726cb144abf..416a6dce5e11 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -302,6 +302,7 @@ static void ehci_quiesce (struct ehci_hcd *ehci) static void end_unlink_async(struct ehci_hcd *ehci); static void unlink_empty_async(struct ehci_hcd *ehci); +static void unlink_empty_async_suspended(struct ehci_hcd *ehci); static void ehci_work(struct ehci_hcd *ehci); static void start_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); static void end_unlink_intr(struct ehci_hcd *ehci, struct ehci_qh *qh); diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 4d3b294f203e..7d06e77f6c4f 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c @@ -328,7 +328,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ehci->rh_state = EHCI_RH_SUSPENDED; end_unlink_async(ehci); - unlink_empty_async(ehci); + unlink_empty_async_suspended(ehci); ehci_handle_intr_unlinks(ehci); end_free_itds(ehci); diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 5464665f0b6a..23d136904285 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -1316,6 +1316,19 @@ static void unlink_empty_async(struct ehci_hcd *ehci) } } +/* The root hub is suspended; unlink all the async QHs */ +static void unlink_empty_async_suspended(struct ehci_hcd *ehci) +{ + struct ehci_qh *qh; + + while (ehci->async->qh_next.qh) { + qh = ehci->async->qh_next.qh; + WARN_ON(!list_empty(&qh->qtd_list)); + single_unlink_async(ehci, qh); + } + start_iaa_cycle(ehci, false); +} + /* makes sure the async qh will become idle */ /* caller must own ehci->lock */ -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 347e0899b1c75d907f01ac883ca38d37fe9bfa42 Mon Sep 17 00:00:00 2001 From: Andy King Date: Thu, 7 Mar 2013 07:29:08 -0800 Subject: VMCI: Fix process-to-process DRGAMs. When sending between processes, we always schedule a work item. Our work info struct has the message embedded in the middle, which means that we end up overwriting subsequent fields when we copy the (variable-length) message into it. Move it to the end of the struct. Acked-by: Dmitry Torokhov Signed-off-by: Andy King Signed-off-by: Greg Kroah-Hartman --- drivers/misc/vmw_vmci/vmci_datagram.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/vmw_vmci/vmci_datagram.c b/drivers/misc/vmw_vmci/vmci_datagram.c index ed5c433cd493..f3cdd904fe4d 100644 --- a/drivers/misc/vmw_vmci/vmci_datagram.c +++ b/drivers/misc/vmw_vmci/vmci_datagram.c @@ -42,9 +42,11 @@ struct datagram_entry { struct delayed_datagram_info { struct datagram_entry *entry; - struct vmci_datagram msg; struct work_struct work; bool in_dg_host_queue; + /* msg and msg_payload must be together. */ + struct vmci_datagram msg; + u8 msg_payload[]; }; /* Number of in-flight host->host datagrams */ -- cgit v1.2.3 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 v1.2.3 From 503bded92da283b2f31d87e054c4c6d30c3c2340 Mon Sep 17 00:00:00 2001 From: Pawel Wieczorkiewicz Date: Wed, 20 Feb 2013 17:26:20 +0100 Subject: tty: atmel_serial_probe(): index of atmel_ports[] fix Index of atmel_ports[ATMEL_MAX_UART] should be smaller than ATMEL_MAX_UART. Signed-off-by: Pawel Wieczorkiewicz Acked-by: Nicolas Ferre Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/atmel_serial.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c index d4a7c241b751..3467462869ce 100644 --- a/drivers/tty/serial/atmel_serial.c +++ b/drivers/tty/serial/atmel_serial.c @@ -158,7 +158,7 @@ struct atmel_uart_port { }; static struct atmel_uart_port atmel_ports[ATMEL_MAX_UART]; -static unsigned long atmel_ports_in_use; +static DECLARE_BITMAP(atmel_ports_in_use, ATMEL_MAX_UART); #ifdef SUPPORT_SYSRQ static struct console atmel_console; @@ -1769,15 +1769,14 @@ static int atmel_serial_probe(struct platform_device *pdev) if (ret < 0) /* port id not found in platform data nor device-tree aliases: * auto-enumerate it */ - ret = find_first_zero_bit(&atmel_ports_in_use, - sizeof(atmel_ports_in_use)); + ret = find_first_zero_bit(atmel_ports_in_use, ATMEL_MAX_UART); - if (ret > ATMEL_MAX_UART) { + if (ret >= ATMEL_MAX_UART) { ret = -ENODEV; goto err; } - if (test_and_set_bit(ret, &atmel_ports_in_use)) { + if (test_and_set_bit(ret, atmel_ports_in_use)) { /* port already in use */ ret = -EBUSY; goto err; @@ -1857,7 +1856,7 @@ static int atmel_serial_remove(struct platform_device *pdev) /* "port" is allocated statically, so we shouldn't free it */ - clear_bit(port->line, &atmel_ports_in_use); + clear_bit(port->line, atmel_ports_in_use); clk_put(atmel_port->clk); -- cgit v1.2.3 From 8b5c913f7ee6464849570bacb6bcd9ef0eaf7dce Mon Sep 17 00:00:00 2001 From: Wang YanQing Date: Tue, 5 Mar 2013 23:16:48 +0800 Subject: serial: 8250_pci: Add WCH CH352 quirk to avoid Xscale detection The code in 8250.c for detecting ARM/XScale UARTs says: * Try writing and reading the UART_IER_UUE bit (b6). * If it works, this is probably one of the Xscale platform's * internal UARTs. If the above passes, it then goes on to: * It's an Xscale. * We'll leave the UART_IER_UUE bit set to 1 (enabled). However, the CH352 uses the UART_IER_UUE as the LOWPOWER function, so it is readable and writable. According to the datasheet: "LOWPOWER:When the bit is 1, close the internal benchmark clock of serial port to set into low-power status. So it essentially gets mis-detected as Xscale, and gets powered down in the process. The device in question where this was seen is listed by lspci as: Serial controller: Device 4348:3253 (rev 10) (prog-if 02 [16550]) Re-using the 353 quirk which just sets flags to fixed and type to 16550 is suitable for fixing the 352 as well. Signed-off-by: Wang YanQing Signed-off-by: Paul Gortmaker Signed-off-by: Greg Kroah-Hartman --- drivers/tty/serial/8250/8250_pci.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index aa76825229dc..26e3a97ab157 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c @@ -1554,6 +1554,7 @@ pci_wch_ch353_setup(struct serial_private *priv, #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001 #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d #define PCI_VENDOR_ID_WCH 0x4348 +#define PCI_DEVICE_ID_WCH_CH352_2S 0x3253 #define PCI_DEVICE_ID_WCH_CH353_4S 0x3453 #define PCI_DEVICE_ID_WCH_CH353_2S1PF 0x5046 #define PCI_DEVICE_ID_WCH_CH353_2S1P 0x7053 @@ -2172,6 +2173,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { .subdevice = PCI_ANY_ID, .setup = pci_wch_ch353_setup, }, + /* WCH CH352 2S card (16550 clone) */ + { + .vendor = PCI_VENDOR_ID_WCH, + .device = PCI_DEVICE_ID_WCH_CH352_2S, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .setup = pci_wch_ch353_setup, + }, /* * ASIX devices with FIFO bug */ @@ -4870,6 +4879,10 @@ static struct pci_device_id serial_pci_tbl[] = { PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_bt_2_115200 }, + { PCI_VENDOR_ID_WCH, PCI_DEVICE_ID_WCH_CH352_2S, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, pbn_b0_bt_2_115200 }, + /* * Commtech, Inc. Fastcom adapters */ -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From fa3daf9aa74a3ac1c87d8188a43d283d06720032 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 11 Mar 2013 15:32:26 -0400 Subject: drm/radeon: fix S/R on VM systems (cayman/TN/SI) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We weren't properly tearing down the VM sub-alloctor on suspend leading to bogus VM PTs on resume. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=60439 Reviewed-by: Christian König Tested-by: Dmitry Cherkasov Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ni.c | 1 + drivers/gpu/drm/radeon/si.c | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index d4c633e12863..e77c9273bc9c 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1771,6 +1771,7 @@ int cayman_resume(struct radeon_device *rdev) int cayman_suspend(struct radeon_device *rdev) { r600_audio_fini(rdev); + radeon_vm_manager_fini(rdev); cayman_cp_enable(rdev, false); cayman_dma_stop(rdev); evergreen_irq_suspend(rdev); diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index 9128120da044..bafbe3216952 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c @@ -4469,6 +4469,7 @@ int si_resume(struct radeon_device *rdev) int si_suspend(struct radeon_device *rdev) { + radeon_vm_manager_fini(rdev); si_cp_enable(rdev, false); cayman_dma_stop(rdev); si_irq_suspend(rdev); -- cgit v1.2.3 From 8f612b23a17dce86fef75407e698de6243cc99a1 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 11 Mar 2013 19:28:39 -0400 Subject: drm/radeon: fix backend map setup on 1 RB trinity boards Need to adjust the backend map depending on which RB is enabled. This is the trinity equivalent of: f7eb97300832f4fe5fe916c5d84cd2e25169330e May fix: https://bugs.freedesktop.org/show_bug.cgi?id=57919 Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ni.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index e77c9273bc9c..a7d3de73be04 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -616,11 +616,22 @@ static void cayman_gpu_init(struct radeon_device *rdev) WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config); WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config); - tmp = gb_addr_config & NUM_PIPES_MASK; - tmp = r6xx_remap_render_backend(rdev, tmp, - rdev->config.cayman.max_backends_per_se * - rdev->config.cayman.max_shader_engines, - CAYMAN_MAX_BACKENDS, disabled_rb_mask); + if ((rdev->config.cayman.max_backends_per_se == 1) && + (rdev->flags & RADEON_IS_IGP)) { + if ((disabled_rb_mask & 3) == 1) { + /* RB0 disabled, RB1 enabled */ + tmp = 0x11111111; + } else { + /* RB1 disabled, RB0 enabled */ + tmp = 0x00000000; + } + } else { + tmp = gb_addr_config & NUM_PIPES_MASK; + tmp = r6xx_remap_render_backend(rdev, tmp, + rdev->config.cayman.max_backends_per_se * + rdev->config.cayman.max_shader_engines, + CAYMAN_MAX_BACKENDS, disabled_rb_mask); + } WREG32(GB_BACKEND_MAP, tmp); cgts_tcc_disable = 0xffff0000; -- cgit v1.2.3 From fa8d387dc3f62062a6b4afbbb2a3438094fd8584 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 12 Mar 2013 12:53:13 -0400 Subject: drm/radeon/benchmark: make sure bo blit copy exists before using it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes a segfault on asics without a blit callback. Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=62239 Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/radeon_benchmark.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index bedda9caadd9..a2f0c243deb2 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -135,13 +135,15 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, sdomain, ddomain, "dma"); } - time = radeon_benchmark_do_move(rdev, size, saddr, daddr, - RADEON_BENCHMARK_COPY_BLIT, n); - if (time < 0) - goto out_cleanup; - if (time > 0) - radeon_benchmark_log_results(n, size, time, - sdomain, ddomain, "blit"); + if (rdev->asic->copy.blit) { + time = radeon_benchmark_do_move(rdev, size, saddr, daddr, + RADEON_BENCHMARK_COPY_BLIT, n); + if (time < 0) + goto out_cleanup; + if (time > 0) + radeon_benchmark_log_results(n, size, time, + sdomain, ddomain, "blit"); + } out_cleanup: if (sobj) { -- cgit v1.2.3 From 271e53dcffa527c853b4f1b0cdedd10bef406a22 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 12 Mar 2013 12:55:56 -0400 Subject: drm/radeon/benchmark: allow same domains for dma copy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove old comment and allow benchmarking moves within the same memory domain for both dma and blit methods. Reviewed-by: Michel Dänzer Signed-off-by: Alex Deucher --- drivers/gpu/drm/radeon/radeon_benchmark.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index a2f0c243deb2..6e05a2e75a46 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c @@ -122,10 +122,7 @@ static void radeon_benchmark_move(struct radeon_device *rdev, unsigned size, goto out_cleanup; } - /* r100 doesn't have dma engine so skip the test */ - /* also, VRAM-to-VRAM test doesn't make much sense for DMA */ - /* skip it as well if domains are the same */ - if ((rdev->asic->copy.dma) && (sdomain != ddomain)) { + if (rdev->asic->copy.dma) { time = radeon_benchmark_do_move(rdev, size, saddr, daddr, RADEON_BENCHMARK_COPY_DMA, n); if (time < 0) -- cgit v1.2.3 From e4d170633fde379f39a90f8a5e7eb619b5d1144d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 8 Mar 2013 13:44:15 -0500 Subject: drm/radeon: add support for Richland APUs Richland APUs are a new version of the Trinity APUs with performance and power management improvements. Reviewed-by: Jerome Glisse Signed-off-by: Alex Deucher Cc: stable@vger.kernel.org --- drivers/gpu/drm/radeon/ni.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index a7d3de73be04..27769e724b6d 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -468,13 +468,19 @@ static void cayman_gpu_init(struct radeon_device *rdev) (rdev->pdev->device == 0x9907) || (rdev->pdev->device == 0x9908) || (rdev->pdev->device == 0x9909) || + (rdev->pdev->device == 0x990B) || + (rdev->pdev->device == 0x990C) || + (rdev->pdev->device == 0x990F) || (rdev->pdev->device == 0x9910) || - (rdev->pdev->device == 0x9917)) { + (rdev->pdev->device == 0x9917) || + (rdev->pdev->device == 0x9999)) { rdev->config.cayman.max_simds_per_se = 6; rdev->config.cayman.max_backends_per_se = 2; } else if ((rdev->pdev->device == 0x9903) || (rdev->pdev->device == 0x9904) || (rdev->pdev->device == 0x990A) || + (rdev->pdev->device == 0x990D) || + (rdev->pdev->device == 0x990E) || (rdev->pdev->device == 0x9913) || (rdev->pdev->device == 0x9918)) { rdev->config.cayman.max_simds_per_se = 4; @@ -483,6 +489,9 @@ static void cayman_gpu_init(struct radeon_device *rdev) (rdev->pdev->device == 0x9990) || (rdev->pdev->device == 0x9991) || (rdev->pdev->device == 0x9994) || + (rdev->pdev->device == 0x9995) || + (rdev->pdev->device == 0x9996) || + (rdev->pdev->device == 0x999A) || (rdev->pdev->device == 0x99A0)) { rdev->config.cayman.max_simds_per_se = 3; rdev->config.cayman.max_backends_per_se = 1; -- cgit v1.2.3 From 1eef1282549d7accdd33ee36d409b039b1f911fb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Mar 2013 09:07:46 -0300 Subject: amd64_edac: Correct DIMM sizes We were filling the csrow size with a wrong value. 16a528ee3975 ("EDAC: Fix csrow size reported in sysfs") tried to address the issue. It fixed the report with the old API but not with the new one. Correct it for the new API too. Signed-off-by: Mauro Carvalho Chehab [ make it a per-csrow accounting regardless of ->channel_count ] Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 14 +++++++++----- drivers/edac/edac_mc_sysfs.c | 13 +++---------- include/linux/edac.h | 1 - 3 files changed, 12 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 910b0116c128..532de775a184 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2048,12 +2048,18 @@ static int init_csrows(struct mem_ctl_info *mci) edac_dbg(1, "MC node: %d, csrow: %d\n", pvt->mc_node_id, i); - if (row_dct0) + if (row_dct0) { nr_pages = amd64_csrow_nr_pages(pvt, 0, i); + csrow->channels[0]->dimm->nr_pages = nr_pages; + } /* K8 has only one DCT */ - if (boot_cpu_data.x86 != 0xf && row_dct1) - nr_pages += amd64_csrow_nr_pages(pvt, 1, i); + if (boot_cpu_data.x86 != 0xf && row_dct1) { + int row_dct1_pages = amd64_csrow_nr_pages(pvt, 1, i); + + csrow->channels[1]->dimm->nr_pages = row_dct1_pages; + nr_pages += row_dct1_pages; + } mtype = amd64_determine_memory_type(pvt, i); @@ -2072,9 +2078,7 @@ static int init_csrows(struct mem_ctl_info *mci) dimm = csrow->channels[j]->dimm; dimm->mtype = mtype; dimm->edac_mode = edac_mode; - dimm->nr_pages = nr_pages; } - csrow->nr_pages = nr_pages; } return empty; diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 0cbf670efa23..4c50a4760db7 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -180,9 +180,6 @@ static ssize_t csrow_size_show(struct device *dev, int i; u32 nr_pages = 0; - if (csrow->mci->csbased) - return sprintf(data, "%u\n", PAGES_TO_MiB(csrow->nr_pages)); - for (i = 0; i < csrow->nr_channels; i++) nr_pages += csrow->channels[i]->dimm->nr_pages; return sprintf(data, "%u\n", PAGES_TO_MiB(nr_pages)); @@ -778,14 +775,10 @@ static ssize_t mci_size_mb_show(struct device *dev, for (csrow_idx = 0; csrow_idx < mci->nr_csrows; csrow_idx++) { struct csrow_info *csrow = mci->csrows[csrow_idx]; - if (csrow->mci->csbased) { - total_pages += csrow->nr_pages; - } else { - for (j = 0; j < csrow->nr_channels; j++) { - struct dimm_info *dimm = csrow->channels[j]->dimm; + for (j = 0; j < csrow->nr_channels; j++) { + struct dimm_info *dimm = csrow->channels[j]->dimm; - total_pages += dimm->nr_pages; - } + total_pages += dimm->nr_pages; } } diff --git a/include/linux/edac.h b/include/linux/edac.h index 4fd4999ccb5b..ab1ea98e767c 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -561,7 +561,6 @@ struct csrow_info { u32 ue_count; /* Uncorrectable Errors for this csrow */ u32 ce_count; /* Correctable Errors for this csrow */ - u32 nr_pages; /* combined pages count of all channels */ struct mem_ctl_info *mci; /* the parent */ -- cgit v1.2.3 From 9713faecff3d071de1208b081d4943b002e9cb1c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 11 Mar 2013 09:28:48 -0300 Subject: EDAC: Merge mci.mem_is_per_rank with mci.csbased Both mci.mem_is_per_rank and mci.csbased denote the same thing: the memory controller is csrows based. Merge both fields into one. There's no need for the driver to actually fill it, as the core detects it by checking if one of the layers has the csrows type as part of the memory hierarchy: if (layers[i].type == EDAC_MC_LAYER_CHIP_SELECT) per_rank = true; Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Borislav Petkov --- drivers/edac/amd64_edac.c | 1 - drivers/edac/edac_mc.c | 6 +++--- drivers/edac/edac_mc_sysfs.c | 2 +- include/linux/edac.h | 6 ++---- 4 files changed, 6 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 532de775a184..e1d13c463c90 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c @@ -2423,7 +2423,6 @@ static int amd64_init_one_instance(struct pci_dev *F2) mci->pvt_info = pvt; mci->pdev = &pvt->F2->dev; - mci->csbased = 1; setup_mci_misc_attrs(mci, fam_type); diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index cdb81aa73ab7..27e86d938262 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -86,7 +86,7 @@ static void edac_mc_dump_dimm(struct dimm_info *dimm, int number) edac_dimm_info_location(dimm, location, sizeof(location)); edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n", - dimm->mci->mem_is_per_rank ? "rank" : "dimm", + dimm->mci->csbased ? "rank" : "dimm", number, location, dimm->csrow, dimm->cschannel); edac_dbg(4, " dimm = %p\n", dimm); edac_dbg(4, " dimm->label = '%s'\n", dimm->label); @@ -341,7 +341,7 @@ struct mem_ctl_info *edac_mc_alloc(unsigned mc_num, memcpy(mci->layers, layers, sizeof(*layer) * n_layers); mci->nr_csrows = tot_csrows; mci->num_cschannel = tot_channels; - mci->mem_is_per_rank = per_rank; + mci->csbased = per_rank; /* * Alocate and fill the csrow/channels structs @@ -1235,7 +1235,7 @@ void edac_mc_handle_error(const enum hw_event_mc_err_type type, * incrementing the compat API counters */ edac_dbg(4, "%s csrows map: (%d,%d)\n", - mci->mem_is_per_rank ? "rank" : "dimm", + mci->csbased ? "rank" : "dimm", dimm->csrow, dimm->cschannel); if (row == -1) row = dimm->csrow; diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 4c50a4760db7..5899a76eec3b 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -609,7 +609,7 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, device_initialize(&dimm->dev); dimm->dev.parent = &mci->dev; - if (mci->mem_is_per_rank) + if (mci->csbased) dev_set_name(&dimm->dev, "rank%d", index); else dev_set_name(&dimm->dev, "dimm%d", index); diff --git a/include/linux/edac.h b/include/linux/edac.h index ab1ea98e767c..0b763276f619 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -675,11 +675,11 @@ struct mem_ctl_info { * sees memory sticks ("dimms"), and the ones that sees memory ranks. * All old memory controllers enumerate memories per rank, but most * of the recent drivers enumerate memories per DIMM, instead. - * When the memory controller is per rank, mem_is_per_rank is true. + * When the memory controller is per rank, csbased is true. */ unsigned n_layers; struct edac_mc_layer *layers; - bool mem_is_per_rank; + bool csbased; /* * DIMM info. Will eventually remove the entire csrows_info some day @@ -740,8 +740,6 @@ struct mem_ctl_info { u32 fake_inject_ue; u16 fake_inject_count; #endif - __u8 csbased : 1, /* csrow-based memory controller */ - __resv : 7; }; #endif -- cgit v1.2.3 From c95246c3a2ac796cfa43e76200ede59cb4a1644f Mon Sep 17 00:00:00 2001 From: Philip J Kelleher Date: Sat, 16 Mar 2013 08:22:25 +0100 Subject: Adding in EEH support to the IBM FlashSystem 70/80 device driver Changes in v2 include: o Fixed spelling of guarantee. o Fixed potential memory leak if slot reset fails out. o Changed list_for_each_entry_safe with list_for_each_entry. Signed-off-by: Philip J Kelleher Signed-off-by: Jens Axboe --- drivers/block/rsxx/core.c | 203 +++++++++++++++++++++++++++++++++++++- drivers/block/rsxx/cregs.c | 59 +++++++++-- drivers/block/rsxx/dma.c | 216 ++++++++++++++++++++++++++++++----------- drivers/block/rsxx/rsxx_priv.h | 25 ++++- 4 files changed, 436 insertions(+), 67 deletions(-) (limited to 'drivers') diff --git a/drivers/block/rsxx/core.c b/drivers/block/rsxx/core.c index cbbdff113f46..93f28191a0ff 100644 --- a/drivers/block/rsxx/core.c +++ b/drivers/block/rsxx/core.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -52,6 +53,13 @@ static DEFINE_IDA(rsxx_disk_ida); static DEFINE_SPINLOCK(rsxx_ida_lock); /*----------------- Interrupt Control & Handling -------------------*/ + +static void rsxx_mask_interrupts(struct rsxx_cardinfo *card) +{ + card->isr_mask = 0; + card->ier_mask = 0; +} + static void __enable_intr(unsigned int *mask, unsigned int intr) { *mask |= intr; @@ -71,7 +79,8 @@ static void __disable_intr(unsigned int *mask, unsigned int intr) */ void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr) { - if (unlikely(card->halt)) + if (unlikely(card->halt) || + unlikely(card->eeh_state)) return; __enable_intr(&card->ier_mask, intr); @@ -80,6 +89,9 @@ void rsxx_enable_ier(struct rsxx_cardinfo *card, unsigned int intr) void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr) { + if (unlikely(card->eeh_state)) + return; + __disable_intr(&card->ier_mask, intr); iowrite32(card->ier_mask, card->regmap + IER); } @@ -87,7 +99,8 @@ void rsxx_disable_ier(struct rsxx_cardinfo *card, unsigned int intr) void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card, unsigned int intr) { - if (unlikely(card->halt)) + if (unlikely(card->halt) || + unlikely(card->eeh_state)) return; __enable_intr(&card->isr_mask, intr); @@ -97,6 +110,9 @@ void rsxx_enable_ier_and_isr(struct rsxx_cardinfo *card, void rsxx_disable_ier_and_isr(struct rsxx_cardinfo *card, unsigned int intr) { + if (unlikely(card->eeh_state)) + return; + __disable_intr(&card->isr_mask, intr); __disable_intr(&card->ier_mask, intr); iowrite32(card->ier_mask, card->regmap + IER); @@ -115,6 +131,9 @@ static irqreturn_t rsxx_isr(int irq, void *pdata) do { reread_isr = 0; + if (unlikely(card->eeh_state)) + break; + isr = ioread32(card->regmap + ISR); if (isr == 0xffffffff) { /* @@ -304,6 +323,179 @@ static int card_shutdown(struct rsxx_cardinfo *card) return 0; } +static void rsxx_eeh_frozen(struct pci_dev *dev) +{ + struct rsxx_cardinfo *card = pci_get_drvdata(dev); + int i; + + dev_warn(&dev->dev, "IBM FlashSystem PCI: preparing for slot reset.\n"); + + card->eeh_state = 1; + rsxx_mask_interrupts(card); + + /* + * We need to guarantee that the write for eeh_state and masking + * interrupts does not become reordered. This will prevent a possible + * race condition with the EEH code. + */ + wmb(); + + pci_disable_device(dev); + + rsxx_eeh_save_issued_dmas(card); + + rsxx_eeh_save_issued_creg(card); + + for (i = 0; i < card->n_targets; i++) { + if (card->ctrl[i].status.buf) + pci_free_consistent(card->dev, STATUS_BUFFER_SIZE8, + card->ctrl[i].status.buf, + card->ctrl[i].status.dma_addr); + if (card->ctrl[i].cmd.buf) + pci_free_consistent(card->dev, COMMAND_BUFFER_SIZE8, + card->ctrl[i].cmd.buf, + card->ctrl[i].cmd.dma_addr); + } +} + +static void rsxx_eeh_failure(struct pci_dev *dev) +{ + struct rsxx_cardinfo *card = pci_get_drvdata(dev); + int i; + + dev_err(&dev->dev, "IBM FlashSystem PCI: disabling failed card.\n"); + + card->eeh_state = 1; + + for (i = 0; i < card->n_targets; i++) + del_timer_sync(&card->ctrl[i].activity_timer); + + rsxx_eeh_cancel_dmas(card); +} + +static int rsxx_eeh_fifo_flush_poll(struct rsxx_cardinfo *card) +{ + unsigned int status; + int iter = 0; + + /* We need to wait for the hardware to reset */ + while (iter++ < 10) { + status = ioread32(card->regmap + PCI_RECONFIG); + + if (status & RSXX_FLUSH_BUSY) { + ssleep(1); + continue; + } + + if (status & RSXX_FLUSH_TIMEOUT) + dev_warn(CARD_TO_DEV(card), "HW: flash controller timeout\n"); + return 0; + } + + /* Hardware failed resetting itself. */ + return -1; +} + +static pci_ers_result_t rsxx_error_detected(struct pci_dev *dev, + enum pci_channel_state error) +{ + if (dev->revision < RSXX_EEH_SUPPORT) + return PCI_ERS_RESULT_NONE; + + if (error == pci_channel_io_perm_failure) { + rsxx_eeh_failure(dev); + return PCI_ERS_RESULT_DISCONNECT; + } + + rsxx_eeh_frozen(dev); + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t rsxx_slot_reset(struct pci_dev *dev) +{ + struct rsxx_cardinfo *card = pci_get_drvdata(dev); + unsigned long flags; + int i; + int st; + + dev_warn(&dev->dev, + "IBM FlashSystem PCI: recovering from slot reset.\n"); + + st = pci_enable_device(dev); + if (st) + goto failed_hw_setup; + + pci_set_master(dev); + + st = rsxx_eeh_fifo_flush_poll(card); + if (st) + goto failed_hw_setup; + + rsxx_dma_queue_reset(card); + + for (i = 0; i < card->n_targets; i++) { + st = rsxx_hw_buffers_init(dev, &card->ctrl[i]); + if (st) + goto failed_hw_buffers_init; + } + + if (card->config_valid) + rsxx_dma_configure(card); + + /* Clears the ISR register from spurious interrupts */ + st = ioread32(card->regmap + ISR); + + card->eeh_state = 0; + + st = rsxx_eeh_remap_dmas(card); + if (st) + goto failed_remap_dmas; + + spin_lock_irqsave(&card->irq_lock, flags); + if (card->n_targets & RSXX_MAX_TARGETS) + rsxx_enable_ier_and_isr(card, CR_INTR_ALL_G); + else + rsxx_enable_ier_and_isr(card, CR_INTR_ALL_C); + spin_unlock_irqrestore(&card->irq_lock, flags); + + rsxx_kick_creg_queue(card); + + for (i = 0; i < card->n_targets; i++) { + spin_lock(&card->ctrl[i].queue_lock); + if (list_empty(&card->ctrl[i].queue)) { + spin_unlock(&card->ctrl[i].queue_lock); + continue; + } + spin_unlock(&card->ctrl[i].queue_lock); + + queue_work(card->ctrl[i].issue_wq, + &card->ctrl[i].issue_dma_work); + } + + dev_info(&dev->dev, "IBM FlashSystem PCI: recovery complete.\n"); + + return PCI_ERS_RESULT_RECOVERED; + +failed_hw_buffers_init: +failed_remap_dmas: + for (i = 0; i < card->n_targets; i++) { + if (card->ctrl[i].status.buf) + pci_free_consistent(card->dev, + STATUS_BUFFER_SIZE8, + card->ctrl[i].status.buf, + card->ctrl[i].status.dma_addr); + if (card->ctrl[i].cmd.buf) + pci_free_consistent(card->dev, + COMMAND_BUFFER_SIZE8, + card->ctrl[i].cmd.buf, + card->ctrl[i].cmd.dma_addr); + } +failed_hw_setup: + rsxx_eeh_failure(dev); + return PCI_ERS_RESULT_DISCONNECT; + +} + /*----------------- Driver Initialization & Setup -------------------*/ /* Returns: 0 if the driver is compatible with the device -1 if the driver is NOT compatible with the device */ @@ -383,6 +575,7 @@ static int rsxx_pci_probe(struct pci_dev *dev, spin_lock_init(&card->irq_lock); card->halt = 0; + card->eeh_state = 0; spin_lock_irq(&card->irq_lock); rsxx_disable_ier_and_isr(card, CR_INTR_ALL); @@ -593,6 +786,11 @@ static void rsxx_pci_shutdown(struct pci_dev *dev) card_shutdown(card); } +static const struct pci_error_handlers rsxx_err_handler = { + .error_detected = rsxx_error_detected, + .slot_reset = rsxx_slot_reset, +}; + static DEFINE_PCI_DEVICE_TABLE(rsxx_pci_ids) = { {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS70_FLASH)}, {PCI_DEVICE(PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_FS80_FLASH)}, @@ -608,6 +806,7 @@ static struct pci_driver rsxx_pci_driver = { .remove = rsxx_pci_remove, .suspend = rsxx_pci_suspend, .shutdown = rsxx_pci_shutdown, + .err_handler = &rsxx_err_handler, }; static int __init rsxx_core_init(void) diff --git a/drivers/block/rsxx/cregs.c b/drivers/block/rsxx/cregs.c index 0539a25877eb..4b5c020a0a65 100644 --- a/drivers/block/rsxx/cregs.c +++ b/drivers/block/rsxx/cregs.c @@ -58,7 +58,7 @@ static struct kmem_cache *creg_cmd_pool; #error Unknown endianess!!! Aborting... #endif -static void copy_to_creg_data(struct rsxx_cardinfo *card, +static int copy_to_creg_data(struct rsxx_cardinfo *card, int cnt8, void *buf, unsigned int stream) @@ -66,6 +66,9 @@ static void copy_to_creg_data(struct rsxx_cardinfo *card, int i = 0; u32 *data = buf; + if (unlikely(card->eeh_state)) + return -EIO; + for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { /* * Firmware implementation makes it necessary to byte swap on @@ -76,10 +79,12 @@ static void copy_to_creg_data(struct rsxx_cardinfo *card, else iowrite32(data[i], card->regmap + CREG_DATA(i)); } + + return 0; } -static void copy_from_creg_data(struct rsxx_cardinfo *card, +static int copy_from_creg_data(struct rsxx_cardinfo *card, int cnt8, void *buf, unsigned int stream) @@ -87,6 +92,9 @@ static void copy_from_creg_data(struct rsxx_cardinfo *card, int i = 0; u32 *data = buf; + if (unlikely(card->eeh_state)) + return -EIO; + for (i = 0; cnt8 > 0; i++, cnt8 -= 4) { /* * Firmware implementation makes it necessary to byte swap on @@ -97,19 +105,32 @@ static void copy_from_creg_data(struct rsxx_cardinfo *card, else data[i] = ioread32(card->regmap + CREG_DATA(i)); } + + return 0; } static void creg_issue_cmd(struct rsxx_cardinfo *card, struct creg_cmd *cmd) { + int st; + + if (unlikely(card->eeh_state)) + return; + iowrite32(cmd->addr, card->regmap + CREG_ADD); iowrite32(cmd->cnt8, card->regmap + CREG_CNT); if (cmd->op == CREG_OP_WRITE) { - if (cmd->buf) - copy_to_creg_data(card, cmd->cnt8, - cmd->buf, cmd->stream); + if (cmd->buf) { + st = copy_to_creg_data(card, cmd->cnt8, + cmd->buf, cmd->stream); + if (st) + return; + } } + if (unlikely(card->eeh_state)) + return; + /* Setting the valid bit will kick off the command. */ iowrite32(cmd->op, card->regmap + CREG_CMD); } @@ -272,7 +293,7 @@ static void creg_cmd_done(struct work_struct *work) goto creg_done; } - copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); + st = copy_from_creg_data(card, cnt8, cmd->buf, cmd->stream); } creg_done: @@ -675,6 +696,32 @@ int rsxx_reg_access(struct rsxx_cardinfo *card, return 0; } +void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card) +{ + struct creg_cmd *cmd = NULL; + + cmd = card->creg_ctrl.active_cmd; + card->creg_ctrl.active_cmd = NULL; + + if (cmd) { + del_timer_sync(&card->creg_ctrl.cmd_timer); + + spin_lock_bh(&card->creg_ctrl.lock); + list_add(&cmd->list, &card->creg_ctrl.queue); + card->creg_ctrl.q_depth++; + card->creg_ctrl.active = 0; + spin_unlock_bh(&card->creg_ctrl.lock); + } +} + +void rsxx_kick_creg_queue(struct rsxx_cardinfo *card) +{ + spin_lock_bh(&card->creg_ctrl.lock); + if (!list_empty(&card->creg_ctrl.queue)) + creg_kick_queue(card); + spin_unlock_bh(&card->creg_ctrl.lock); +} + /*------------ Initialization & Setup --------------*/ int rsxx_creg_setup(struct rsxx_cardinfo *card) { diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c index efd75b55a670..60d344d002ec 100644 --- a/drivers/block/rsxx/dma.c +++ b/drivers/block/rsxx/dma.c @@ -81,9 +81,6 @@ enum rsxx_hw_status { HW_STATUS_FAULT = 0x08, }; -#define STATUS_BUFFER_SIZE8 4096 -#define COMMAND_BUFFER_SIZE8 4096 - static struct kmem_cache *rsxx_dma_pool; struct dma_tracker { @@ -122,7 +119,7 @@ static unsigned int rsxx_get_dma_tgt(struct rsxx_cardinfo *card, u64 addr8) return tgt; } -static void rsxx_dma_queue_reset(struct rsxx_cardinfo *card) +void rsxx_dma_queue_reset(struct rsxx_cardinfo *card) { /* Reset all DMA Command/Status Queues */ iowrite32(DMA_QUEUE_RESET, card->regmap + RESET); @@ -210,7 +207,8 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card) u32 q_depth = 0; u32 intr_coal; - if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE) + if (card->config.data.intr_coal.mode != RSXX_INTR_COAL_AUTO_TUNE || + unlikely(card->eeh_state)) return; for (i = 0; i < card->n_targets; i++) @@ -223,31 +221,26 @@ static void dma_intr_coal_auto_tune(struct rsxx_cardinfo *card) } /*----------------- RSXX DMA Handling -------------------*/ -static void rsxx_complete_dma(struct rsxx_cardinfo *card, +static void rsxx_complete_dma(struct rsxx_dma_ctrl *ctrl, struct rsxx_dma *dma, unsigned int status) { if (status & DMA_SW_ERR) - printk_ratelimited(KERN_ERR - "SW Error in DMA(cmd x%02x, laddr x%08x)\n", - dma->cmd, dma->laddr); + ctrl->stats.dma_sw_err++; if (status & DMA_HW_FAULT) - printk_ratelimited(KERN_ERR - "HW Fault in DMA(cmd x%02x, laddr x%08x)\n", - dma->cmd, dma->laddr); + ctrl->stats.dma_hw_fault++; if (status & DMA_CANCELLED) - printk_ratelimited(KERN_ERR - "DMA Cancelled(cmd x%02x, laddr x%08x)\n", - dma->cmd, dma->laddr); + ctrl->stats.dma_cancelled++; if (dma->dma_addr) - pci_unmap_page(card->dev, dma->dma_addr, get_dma_size(dma), + pci_unmap_page(ctrl->card->dev, dma->dma_addr, + get_dma_size(dma), dma->cmd == HW_CMD_BLK_WRITE ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (dma->cb) - dma->cb(card, dma->cb_data, status ? 1 : 0); + dma->cb(ctrl->card, dma->cb_data, status ? 1 : 0); kmem_cache_free(rsxx_dma_pool, dma); } @@ -330,14 +323,15 @@ static void rsxx_handle_dma_error(struct rsxx_dma_ctrl *ctrl, if (requeue_cmd) rsxx_requeue_dma(ctrl, dma); else - rsxx_complete_dma(ctrl->card, dma, status); + rsxx_complete_dma(ctrl, dma, status); } static void dma_engine_stalled(unsigned long data) { struct rsxx_dma_ctrl *ctrl = (struct rsxx_dma_ctrl *)data; - if (atomic_read(&ctrl->stats.hw_q_depth) == 0) + if (atomic_read(&ctrl->stats.hw_q_depth) == 0 || + unlikely(ctrl->card->eeh_state)) return; if (ctrl->cmd.idx != ioread32(ctrl->regmap + SW_CMD_IDX)) { @@ -369,7 +363,8 @@ static void rsxx_issue_dmas(struct work_struct *work) ctrl = container_of(work, struct rsxx_dma_ctrl, issue_dma_work); hw_cmd_buf = ctrl->cmd.buf; - if (unlikely(ctrl->card->halt)) + if (unlikely(ctrl->card->halt) || + unlikely(ctrl->card->eeh_state)) return; while (1) { @@ -397,7 +392,7 @@ static void rsxx_issue_dmas(struct work_struct *work) */ if (unlikely(ctrl->card->dma_fault)) { push_tracker(ctrl->trackers, tag); - rsxx_complete_dma(ctrl->card, dma, DMA_CANCELLED); + rsxx_complete_dma(ctrl, dma, DMA_CANCELLED); continue; } @@ -435,6 +430,12 @@ static void rsxx_issue_dmas(struct work_struct *work) atomic_add(cmds_pending, &ctrl->stats.hw_q_depth); mod_timer(&ctrl->activity_timer, jiffies + DMA_ACTIVITY_TIMEOUT); + + if (unlikely(ctrl->card->eeh_state)) { + del_timer_sync(&ctrl->activity_timer); + return; + } + iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); } } @@ -453,7 +454,8 @@ static void rsxx_dma_done(struct work_struct *work) hw_st_buf = ctrl->status.buf; if (unlikely(ctrl->card->halt) || - unlikely(ctrl->card->dma_fault)) + unlikely(ctrl->card->dma_fault) || + unlikely(ctrl->card->eeh_state)) return; count = le16_to_cpu(hw_st_buf[ctrl->status.idx].count); @@ -498,7 +500,7 @@ static void rsxx_dma_done(struct work_struct *work) if (status) rsxx_handle_dma_error(ctrl, dma, status); else - rsxx_complete_dma(ctrl->card, dma, 0); + rsxx_complete_dma(ctrl, dma, 0); push_tracker(ctrl->trackers, tag); @@ -717,20 +719,54 @@ bvec_err: /*----------------- DMA Engine Initialization & Setup -------------------*/ +int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl) +{ + ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, + &ctrl->status.dma_addr); + ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, + &ctrl->cmd.dma_addr); + if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) + return -ENOMEM; + + memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8); + iowrite32(lower_32_bits(ctrl->status.dma_addr), + ctrl->regmap + SB_ADD_LO); + iowrite32(upper_32_bits(ctrl->status.dma_addr), + ctrl->regmap + SB_ADD_HI); + + memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8); + iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO); + iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI); + + ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT); + if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) { + dev_crit(&dev->dev, "Failed reading status cnt x%x\n", + ctrl->status.idx); + return -EINVAL; + } + iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT); + iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT); + + ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX); + if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) { + dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n", + ctrl->status.idx); + return -EINVAL; + } + iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); + iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); + + return 0; +} + static int rsxx_dma_ctrl_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl) { int i; + int st; memset(&ctrl->stats, 0, sizeof(ctrl->stats)); - ctrl->status.buf = pci_alloc_consistent(dev, STATUS_BUFFER_SIZE8, - &ctrl->status.dma_addr); - ctrl->cmd.buf = pci_alloc_consistent(dev, COMMAND_BUFFER_SIZE8, - &ctrl->cmd.dma_addr); - if (ctrl->status.buf == NULL || ctrl->cmd.buf == NULL) - return -ENOMEM; - ctrl->trackers = vmalloc(DMA_TRACKER_LIST_SIZE8); if (!ctrl->trackers) return -ENOMEM; @@ -760,33 +796,9 @@ static int rsxx_dma_ctrl_init(struct pci_dev *dev, INIT_WORK(&ctrl->issue_dma_work, rsxx_issue_dmas); INIT_WORK(&ctrl->dma_done_work, rsxx_dma_done); - memset(ctrl->status.buf, 0xac, STATUS_BUFFER_SIZE8); - iowrite32(lower_32_bits(ctrl->status.dma_addr), - ctrl->regmap + SB_ADD_LO); - iowrite32(upper_32_bits(ctrl->status.dma_addr), - ctrl->regmap + SB_ADD_HI); - - memset(ctrl->cmd.buf, 0x83, COMMAND_BUFFER_SIZE8); - iowrite32(lower_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_LO); - iowrite32(upper_32_bits(ctrl->cmd.dma_addr), ctrl->regmap + CB_ADD_HI); - - ctrl->status.idx = ioread32(ctrl->regmap + HW_STATUS_CNT); - if (ctrl->status.idx > RSXX_MAX_OUTSTANDING_CMDS) { - dev_crit(&dev->dev, "Failed reading status cnt x%x\n", - ctrl->status.idx); - return -EINVAL; - } - iowrite32(ctrl->status.idx, ctrl->regmap + HW_STATUS_CNT); - iowrite32(ctrl->status.idx, ctrl->regmap + SW_STATUS_CNT); - - ctrl->cmd.idx = ioread32(ctrl->regmap + HW_CMD_IDX); - if (ctrl->cmd.idx > RSXX_MAX_OUTSTANDING_CMDS) { - dev_crit(&dev->dev, "Failed reading cmd cnt x%x\n", - ctrl->status.idx); - return -EINVAL; - } - iowrite32(ctrl->cmd.idx, ctrl->regmap + HW_CMD_IDX); - iowrite32(ctrl->cmd.idx, ctrl->regmap + SW_CMD_IDX); + st = rsxx_hw_buffers_init(dev, ctrl); + if (st) + return st; return 0; } @@ -822,7 +834,7 @@ static int rsxx_dma_stripe_setup(struct rsxx_cardinfo *card, return 0; } -static int rsxx_dma_configure(struct rsxx_cardinfo *card) +int rsxx_dma_configure(struct rsxx_cardinfo *card) { u32 intr_coal; @@ -968,6 +980,94 @@ void rsxx_dma_destroy(struct rsxx_cardinfo *card) } } +void rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card) +{ + int i; + int j; + int cnt; + struct rsxx_dma *dma; + struct list_head issued_dmas[card->n_targets]; + + for (i = 0; i < card->n_targets; i++) { + INIT_LIST_HEAD(&issued_dmas[i]); + cnt = 0; + for (j = 0; j < RSXX_MAX_OUTSTANDING_CMDS; j++) { + dma = get_tracker_dma(card->ctrl[i].trackers, j); + if (dma == NULL) + continue; + + if (dma->cmd == HW_CMD_BLK_WRITE) + card->ctrl[i].stats.writes_issued--; + else if (dma->cmd == HW_CMD_BLK_DISCARD) + card->ctrl[i].stats.discards_issued--; + else + card->ctrl[i].stats.reads_issued--; + + list_add_tail(&dma->list, &issued_dmas[i]); + push_tracker(card->ctrl[i].trackers, j); + cnt++; + } + + spin_lock(&card->ctrl[i].queue_lock); + list_splice(&issued_dmas[i], &card->ctrl[i].queue); + + atomic_sub(cnt, &card->ctrl[i].stats.hw_q_depth); + card->ctrl[i].stats.sw_q_depth += cnt; + card->ctrl[i].e_cnt = 0; + + list_for_each_entry(dma, &card->ctrl[i].queue, list) { + if (dma->dma_addr) + pci_unmap_page(card->dev, dma->dma_addr, + get_dma_size(dma), + dma->cmd == HW_CMD_BLK_WRITE ? + PCI_DMA_TODEVICE : + PCI_DMA_FROMDEVICE); + } + spin_unlock(&card->ctrl[i].queue_lock); + } +} + +void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card) +{ + struct rsxx_dma *dma; + struct rsxx_dma *tmp; + int i; + + for (i = 0; i < card->n_targets; i++) { + spin_lock(&card->ctrl[i].queue_lock); + list_for_each_entry_safe(dma, tmp, &card->ctrl[i].queue, list) { + list_del(&dma->list); + + rsxx_complete_dma(&card->ctrl[i], dma, DMA_CANCELLED); + } + spin_unlock(&card->ctrl[i].queue_lock); + } +} + +int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card) +{ + struct rsxx_dma *dma; + struct rsxx_dma *tmp; + int i; + + for (i = 0; i < card->n_targets; i++) { + spin_lock(&card->ctrl[i].queue_lock); + list_for_each_entry(dma, &card->ctrl[i].queue, list) { + dma->dma_addr = pci_map_page(card->dev, dma->page, + dma->pg_off, get_dma_size(dma), + dma->cmd == HW_CMD_BLK_WRITE ? + PCI_DMA_TODEVICE : + PCI_DMA_FROMDEVICE); + if (!dma->dma_addr) { + kmem_cache_free(rsxx_dma_pool, dma); + return -ENOMEM; + } + } + spin_unlock(&card->ctrl[i].queue_lock); + } + + return 0; +} int rsxx_dma_init(void) { diff --git a/drivers/block/rsxx/rsxx_priv.h b/drivers/block/rsxx/rsxx_priv.h index f5a95f75bd57..8a7ac87f1dc5 100644 --- a/drivers/block/rsxx/rsxx_priv.h +++ b/drivers/block/rsxx/rsxx_priv.h @@ -64,6 +64,9 @@ struct proc_cmd; #define RSXX_MAX_OUTSTANDING_CMDS 255 #define RSXX_CS_IDX_MASK 0xff +#define STATUS_BUFFER_SIZE8 4096 +#define COMMAND_BUFFER_SIZE8 4096 + #define RSXX_MAX_TARGETS 8 struct dma_tracker_list; @@ -88,6 +91,9 @@ struct rsxx_dma_stats { u32 discards_failed; u32 done_rescheduled; u32 issue_rescheduled; + u32 dma_sw_err; + u32 dma_hw_fault; + u32 dma_cancelled; u32 sw_q_depth; /* Number of DMAs on the SW queue. */ atomic_t hw_q_depth; /* Number of DMAs queued to HW. */ }; @@ -113,6 +119,7 @@ struct rsxx_dma_ctrl { struct rsxx_cardinfo { struct pci_dev *dev; unsigned int halt; + unsigned int eeh_state; void __iomem *regmap; spinlock_t irq_lock; @@ -221,6 +228,7 @@ enum rsxx_pci_regmap { PERF_RD512_HI = 0xac, PERF_WR512_LO = 0xb0, PERF_WR512_HI = 0xb4, + PCI_RECONFIG = 0xb8, }; enum rsxx_intr { @@ -234,6 +242,8 @@ enum rsxx_intr { CR_INTR_DMA5 = 0x00000080, CR_INTR_DMA6 = 0x00000100, CR_INTR_DMA7 = 0x00000200, + CR_INTR_ALL_C = 0x0000003f, + CR_INTR_ALL_G = 0x000003ff, CR_INTR_DMA_ALL = 0x000003f5, CR_INTR_ALL = 0xffffffff, }; @@ -250,8 +260,14 @@ enum rsxx_pci_reset { DMA_QUEUE_RESET = 0x00000001, }; +enum rsxx_hw_fifo_flush { + RSXX_FLUSH_BUSY = 0x00000002, + RSXX_FLUSH_TIMEOUT = 0x00000004, +}; + enum rsxx_pci_revision { RSXX_DISCARD_SUPPORT = 2, + RSXX_EEH_SUPPORT = 3, }; enum rsxx_creg_cmd { @@ -357,11 +373,17 @@ int rsxx_dma_setup(struct rsxx_cardinfo *card); void rsxx_dma_destroy(struct rsxx_cardinfo *card); int rsxx_dma_init(void); void rsxx_dma_cleanup(void); +void rsxx_dma_queue_reset(struct rsxx_cardinfo *card); +int rsxx_dma_configure(struct rsxx_cardinfo *card); int rsxx_dma_queue_bio(struct rsxx_cardinfo *card, struct bio *bio, atomic_t *n_dmas, rsxx_dma_cb cb, void *cb_data); +int rsxx_hw_buffers_init(struct pci_dev *dev, struct rsxx_dma_ctrl *ctrl); +void rsxx_eeh_save_issued_dmas(struct rsxx_cardinfo *card); +void rsxx_eeh_cancel_dmas(struct rsxx_cardinfo *card); +int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card); /***** cregs.c *****/ int rsxx_creg_write(struct rsxx_cardinfo *card, u32 addr, @@ -386,10 +408,11 @@ int rsxx_creg_setup(struct rsxx_cardinfo *card); void rsxx_creg_destroy(struct rsxx_cardinfo *card); int rsxx_creg_init(void); void rsxx_creg_cleanup(void); - int rsxx_reg_access(struct rsxx_cardinfo *card, struct rsxx_reg_access __user *ucmd, int read); +void rsxx_eeh_save_issued_creg(struct rsxx_cardinfo *card); +void rsxx_kick_creg_queue(struct rsxx_cardinfo *card); -- cgit v1.2.3 From 351a2c6e7d265f97799ec7f6b1dde7fc7cb4b92d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Sat, 16 Mar 2013 10:10:48 +0100 Subject: rsxx: fix missing unlock on error return in rsxx_eeh_remap_dmas() Spotted by Fenguan Wu's super build robot. Signed-off-by: Jens Axboe --- drivers/block/rsxx/dma.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/block/rsxx/dma.c b/drivers/block/rsxx/dma.c index 60d344d002ec..d523e9c56578 100644 --- a/drivers/block/rsxx/dma.c +++ b/drivers/block/rsxx/dma.c @@ -1059,6 +1059,7 @@ int rsxx_eeh_remap_dmas(struct rsxx_cardinfo *card) PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); if (!dma->dma_addr) { + spin_unlock(&card->ctrl[i].queue_lock); kmem_cache_free(rsxx_dma_pool, dma); return -ENOMEM; } -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 1e8bbe6cd02fc300c88bd48244ce61ad9c7d1776 Mon Sep 17 00:00:00 2001 From: Bjørn Mork Date: Thu, 14 Mar 2013 01:05:13 +0000 Subject: net: cdc_ncm, cdc_mbim: allow user to prefer NCM for backwards compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit commit bd329e1 ("net: cdc_ncm: do not bind to NCM compatible MBIM devices") introduced a new policy, preferring MBIM for dual NCM/MBIM functions if the cdc_mbim driver was enabled. This caused a regression for users wanting to use NCM. Devices implementing NCM backwards compatibility according to section 3.2 of the MBIM v1.0 specification allow either NCM or MBIM on a single USB function, using different altsettings. The cdc_ncm and cdc_mbim drivers will both probe such functions, and must agree on a common policy for selecting either MBIM or NCM. Until now, this policy has been set at build time based on CONFIG_USB_NET_CDC_MBIM. Use a module parameter to set the system policy at runtime, allowing the user to prefer NCM on systems with the cdc_mbim driver. Cc: Greg Suarez Cc: Alexey Orishko Reported-by: Geir Haatveit Reported-by: Tommi Kyntola Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=54791 Signed-off-by: Bjørn Mork Signed-off-by: David S. Miller --- drivers/net/usb/cdc_mbim.c | 11 +--------- drivers/net/usb/cdc_ncm.c | 49 +++++++++++++++++++++++++++++---------------- include/linux/usb/cdc_ncm.h | 1 + 3 files changed, 34 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/usb/cdc_mbim.c b/drivers/net/usb/cdc_mbim.c index 248d2dc765a5..16c842997291 100644 --- a/drivers/net/usb/cdc_mbim.c +++ b/drivers/net/usb/cdc_mbim.c @@ -68,18 +68,9 @@ static int cdc_mbim_bind(struct usbnet *dev, struct usb_interface *intf) struct cdc_ncm_ctx *ctx; struct usb_driver *subdriver = ERR_PTR(-ENODEV); int ret = -ENODEV; - u8 data_altsetting = CDC_NCM_DATA_ALTSETTING_NCM; + u8 data_altsetting = cdc_ncm_select_altsetting(dev, intf); struct cdc_mbim_state *info = (void *)&dev->data; - /* see if interface supports MBIM alternate setting */ - if (intf->num_altsetting == 2) { - if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) - usb_set_interface(dev->udev, - intf->cur_altsetting->desc.bInterfaceNumber, - CDC_NCM_COMM_ALTSETTING_MBIM); - data_altsetting = CDC_NCM_DATA_ALTSETTING_MBIM; - } - /* Probably NCM, defer for cdc_ncm_bind */ if (!cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) goto err; diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 61b74a2b89ac..4709fa3497cf 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c @@ -55,6 +55,14 @@ #define DRIVER_VERSION "14-Mar-2012" +#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) +static bool prefer_mbim = true; +#else +static bool prefer_mbim; +#endif +module_param(prefer_mbim, bool, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions"); + static void cdc_ncm_txpath_bh(unsigned long param); static void cdc_ncm_tx_timeout_start(struct cdc_ncm_ctx *ctx); static enum hrtimer_restart cdc_ncm_tx_timer_cb(struct hrtimer *hr_timer); @@ -550,9 +558,12 @@ void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf) } EXPORT_SYMBOL_GPL(cdc_ncm_unbind); -static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) +/* Select the MBIM altsetting iff it is preferred and available, + * returning the number of the corresponding data interface altsetting + */ +u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf) { - int ret; + struct usb_host_interface *alt; /* The MBIM spec defines a NCM compatible default altsetting, * which we may have matched: @@ -568,23 +579,27 @@ static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) * endpoint descriptors, shall be constructed according to * the rules given in section 6 (USB Device Model) of this * specification." - * - * Do not bind to such interfaces, allowing cdc_mbim to handle - * them */ -#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) - if ((intf->num_altsetting == 2) && - !usb_set_interface(dev->udev, - intf->cur_altsetting->desc.bInterfaceNumber, - CDC_NCM_COMM_ALTSETTING_MBIM)) { - if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) - return -ENODEV; - else - usb_set_interface(dev->udev, - intf->cur_altsetting->desc.bInterfaceNumber, - CDC_NCM_COMM_ALTSETTING_NCM); + if (prefer_mbim && intf->num_altsetting == 2) { + alt = usb_altnum_to_altsetting(intf, CDC_NCM_COMM_ALTSETTING_MBIM); + if (alt && cdc_ncm_comm_intf_is_mbim(alt) && + !usb_set_interface(dev->udev, + intf->cur_altsetting->desc.bInterfaceNumber, + CDC_NCM_COMM_ALTSETTING_MBIM)) + return CDC_NCM_DATA_ALTSETTING_MBIM; } -#endif + return CDC_NCM_DATA_ALTSETTING_NCM; +} +EXPORT_SYMBOL_GPL(cdc_ncm_select_altsetting); + +static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) +{ + int ret; + + /* MBIM backwards compatible function? */ + cdc_ncm_select_altsetting(dev, intf); + if (cdc_ncm_comm_intf_is_mbim(intf->cur_altsetting)) + return -ENODEV; /* NCM data altsetting is always 1 */ ret = cdc_ncm_bind_common(dev, intf, 1); diff --git a/include/linux/usb/cdc_ncm.h b/include/linux/usb/cdc_ncm.h index 3b8f9d4fc3fe..cc25b70af33c 100644 --- a/include/linux/usb/cdc_ncm.h +++ b/include/linux/usb/cdc_ncm.h @@ -127,6 +127,7 @@ struct cdc_ncm_ctx { u16 connected; }; +extern u8 cdc_ncm_select_altsetting(struct usbnet *dev, struct usb_interface *intf); extern int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_altsetting); extern void cdc_ncm_unbind(struct usbnet *dev, struct usb_interface *intf); extern struct sk_buff *cdc_ncm_fill_tx_frame(struct cdc_ncm_ctx *ctx, struct sk_buff *skb, __le32 sign); -- cgit v1.2.3 From 8008f6e173c239ea9b2423a937aaf85c3157a306 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Mar 2013 11:56:41 +0000 Subject: isdn: hisax: netjet requires VIRT_TO_BUS Disabling CONFIG_VIRT_TO_BUS on ARM showed that the hisax netjet driver depends on this deprecated functionality but is not marked so in Kconfig. Rather than adding ARM to the already long list of architectures that this driver is broken on, this patch adds 'depends on VIRT_TO_BUS' and removes the dependency on !SPARC, which is also implied by that. Signed-off-by: Arnd Bergmann Cc: Karsten Keil Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/isdn/hisax/Kconfig | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 5313c9ea44dc..d9edcc94c2a8 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig @@ -237,7 +237,8 @@ config HISAX_MIC config HISAX_NETJET bool "NETjet card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) + depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) + depends on VIRT_TO_BUS help This enables HiSax support for the NetJet from Traverse Technologies. @@ -248,7 +249,8 @@ config HISAX_NETJET config HISAX_NETJET_U bool "NETspider U card" - depends on PCI && (BROKEN || !(SPARC || PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) + depends on PCI && (BROKEN || !(PPC || PARISC || M68K || (MIPS && !CPU_LITTLE_ENDIAN) || FRV || (XTENSA && !CPU_LITTLE_ENDIAN))) + depends on VIRT_TO_BUS help This enables HiSax support for the Netspider U interface ISDN card from Traverse Technologies. -- cgit v1.2.3 From db0b82760ef84562b5c0fa880c22b4f352545554 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Mar 2013 11:56:42 +0000 Subject: ethernet/tulip: DE4x5 needs VIRT_TO_BUS The automated ARM build tests have shown that the tulip de4x5 driver uses the old-style virt_to_bus() interface on some architectures. Alpha, Sparc and PowerPC did not hit this problem, because they use a different code path, and most other architectures actually do provide VIRT_TO_BUS. Signed-off-by: Arnd Bergmann Cc: Grant Grundler Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller --- drivers/net/ethernet/dec/tulip/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/dec/tulip/Kconfig b/drivers/net/ethernet/dec/tulip/Kconfig index 0c37fb2cc867..1df33c799c00 100644 --- a/drivers/net/ethernet/dec/tulip/Kconfig +++ b/drivers/net/ethernet/dec/tulip/Kconfig @@ -108,6 +108,7 @@ config TULIP_DM910X config DE4X5 tristate "Generic DECchip & DIGITAL EtherWORKS PCI/EISA" depends on (PCI || EISA) + depends on VIRT_TO_BUS || ALPHA || PPC || SPARC select CRC32 ---help--- This is support for the DIGITAL series of PCI/EISA Ethernet cards. -- cgit v1.2.3 From 75b9b61bb8a18e75afe7b10dd55681e748fa27df Mon Sep 17 00:00:00 2001 From: Mugunthan V N Date: Fri, 15 Mar 2013 04:10:16 +0000 Subject: drivers: net: ethernet: ti: davinci_emac: fix usage of cpdma_check_free_tx_desc() Fix which was done in the following commit in cpsw driver has to be taken forward to davinci emac driver as well. commit d35162f89b8f00537d7b240b76d2d0e8b8d29aa0 Author: Daniel Mack Date: Tue Mar 12 06:31:19 2013 +0000 net: ethernet: cpsw: fix usage of cpdma_check_free_tx_desc() Commit fae50823d0 ("net: ethernet: davinci_cpdma: Add boundary for rx and tx descriptors") introduced a function to check the current allocation state of tx packets. The return value is taken into account to stop the netqork queue on the adapter in case there are no free slots. However, cpdma_check_free_tx_desc() returns 'true' if there is room in the bitmap, not 'false', so the usage of the function is wrong. Reported-by: Prabhakar Lad Tested-by: Prabhakar Lad Signed-off-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 52c05366599a..ae1b77aa199f 100644 --- a/drivers/net/ethernet/ti/davinci_emac.c +++ b/drivers/net/ethernet/ti/davinci_emac.c @@ -1102,7 +1102,7 @@ static int emac_dev_xmit(struct sk_buff *skb, struct net_device *ndev) /* If there is no more tx desc left free then we need to * tell the kernel to stop sending us tx frames. */ - if (unlikely(cpdma_check_free_tx_desc(priv->txchan))) + if (unlikely(!cpdma_check_free_tx_desc(priv->txchan))) netif_stop_queue(ndev); return NETDEV_TX_OK; -- cgit v1.2.3 From 722c6f585088a2c392b4c5d01b87a584bb8fb73f Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Fri, 15 Mar 2013 05:27:54 +0000 Subject: bnx2x: add missing napi deletion in error path If the hardware initialization fails in bnx2x_nic_load() after adding napi objects, they would not be deleted. A subsequent attempt to unload the bnx2x module detects a corruption in the napi list. Add the missing napi deletion to the error path. Signed-off-by: Michal Schmidt Acked-by: Dmitry Kravkov Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 1 + 1 file changed, 1 insertion(+) (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..4046f97378c2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c @@ -2760,6 +2760,7 @@ load_error2: bp->port.pmf = 0; load_error1: bnx2x_napi_disable(bp); + bnx2x_del_all_napi(bp); /* clear pf_load status, as it was already set */ if (IS_PF(bp)) -- cgit v1.2.3 From 46aa92d1ba162b4b3d6b7102440e459d4e4ee255 Mon Sep 17 00:00:00 2001 From: "Michael S. Tsirkin" Date: Sun, 17 Mar 2013 02:46:09 +0000 Subject: vhost/net: fix heads usage of ubuf_info ubuf info allocator uses guest controlled head as an index, so a malicious guest could put the same head entry in the ring twice, and we will get two callbacks on the same value. To fix use upend_idx which is guaranteed to be unique. Reported-by: Rusty Russell Signed-off-by: Michael S. Tsirkin Cc: stable@kernel.org Signed-off-by: David S. Miller --- drivers/vhost/net.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 959b1cd89e6a..ec6fb3fa59bb 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -339,7 +339,8 @@ static void handle_tx(struct vhost_net *net) msg.msg_controllen = 0; ubufs = NULL; } else { - struct ubuf_info *ubuf = &vq->ubuf_info[head]; + struct ubuf_info *ubuf; + ubuf = vq->ubuf_info + vq->upend_idx; vq->heads[vq->upend_idx].len = VHOST_DMA_IN_PROGRESS; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 3b4f819d5eac94ba8fe5e8c061f6dabfe8d7b22c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 11 Mar 2013 18:40:16 +0100 Subject: Revert "drm/i915: try to train DP even harder" This reverts commit 0d71068835e2610576d369d6d4cbf90e0f802a71. Not only that the commit introduces a bogus check (voltage_tries == 5 will never meet at the inserted code path), it brings the i915 driver into an endless dp-train loop on HP Z1 desktop machine with IVY+eDP. At least reverting this commit recovers the framebuffer (but X is still broken by other reasons...) Cc: Signed-off-by: Takashi Iwai Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 6f728e5ee793..d46dde5a51e3 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1930,7 +1930,7 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) for (i = 0; i < intel_dp->lane_count; i++) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) break; - if (i == intel_dp->lane_count && voltage_tries == 5) { + if (i == intel_dp->lane_count) { ++loop_tries; if (loop_tries == 5) { DRM_DEBUG_KMS("too many full retries, give up\n"); -- cgit v1.2.3 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 v1.2.3 From 7ae9712c60698ae2870fd115cb3ef4449a615509 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Tue, 5 Mar 2013 10:26:30 +0100 Subject: drm/nv40/therm: improve selection between the old and the new style The condition to select between the old and new style was a thinko as rnndb orders chipsets based on their release date (or general chronologie hw-wise) and not based on their chipset number. As the nv40 family is a mess when it comes to numbers, this patch introduces a switch-based selection between the old and new style. Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | 50 ++++++++++++++++++------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index 0f5363edb964..d8f43252c048 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -29,42 +29,68 @@ struct nv40_therm_priv { struct nouveau_therm_priv base; }; +enum nv40_sensor_style { INVALID_STYLE = -1, OLD_STYLE = 0, NEW_STYLE = 1 }; + +static enum nv40_sensor_style +nv40_sensor_style(struct nouveau_therm *therm) +{ + struct nouveau_device *device = nv_device(therm); + + switch (device->chipset) { + case 0x43: + case 0x44: + case 0x4a: + case 0x47: + return OLD_STYLE; + + case 0x46: + case 0x49: + case 0x4b: + case 0x4e: + case 0x4c: + case 0x67: + case 0x68: + case 0x63: + return NEW_STYLE; + default: + return INVALID_STYLE; + } +} + static int nv40_sensor_setup(struct nouveau_therm *therm) { - struct nouveau_device *device = nv_device(therm); + enum nv40_sensor_style style = nv40_sensor_style(therm); /* enable ADC readout and disable the ALARM threshold */ - if (device->chipset >= 0x46) { + if (style == NEW_STYLE) { nv_mask(therm, 0x15b8, 0x80000000, 0); nv_wr32(therm, 0x15b0, 0x80003fff); mdelay(10); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0x3fff; - } else { + } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); return nv_rd32(therm, 0x15b4) & 0xff; - } + } else + return -ENODEV; } static int nv40_temp_get(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; - struct nouveau_device *device = nv_device(therm); struct nvbios_therm_sensor *sensor = &priv->bios_sensor; + enum nv40_sensor_style style = nv40_sensor_style(therm); int core_temp; - if (device->chipset >= 0x46) { + if (style == NEW_STYLE) { nv_wr32(therm, 0x15b0, 0x80003fff); core_temp = nv_rd32(therm, 0x15b4) & 0x3fff; - } else { + } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); core_temp = nv_rd32(therm, 0x15b4) & 0xff; - } - - /* Setup the sensor if the temperature is 0 */ - if (core_temp == 0) - core_temp = nv40_sensor_setup(therm); + } else + return -ENODEV; if (sensor->slope_div == 0) sensor->slope_div = 1; -- cgit v1.2.3 From eea4eb14a0f74f806e7a458f174f880744a68bdd Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Tue, 5 Mar 2013 10:35:20 +0100 Subject: drm/nv40/therm: increase the sensor's settling delay to 20ms Based on my experience, 10ms wasn't always enough. Let's bump that to a little more. If this turns out to be insufficient-enough again, then an approach based on letting the sensor settle for several seconds before starting polling on the temperature would be better suited. This way, boot time wouldn't be impacted by those waits too much. Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index d8f43252c048..0575af5328ec 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -66,10 +66,11 @@ nv40_sensor_setup(struct nouveau_therm *therm) if (style == NEW_STYLE) { nv_mask(therm, 0x15b8, 0x80000000, 0); nv_wr32(therm, 0x15b0, 0x80003fff); - mdelay(10); /* wait for the temperature to stabilize */ + mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0x3fff; } else if (style == OLD_STYLE) { nv_wr32(therm, 0x15b0, 0xff); + mdelay(20); /* wait for the temperature to stabilize */ return nv_rd32(therm, 0x15b4) & 0xff; } else return -ENODEV; -- cgit v1.2.3 From 7591782b9f30a5a8bcbba5744c85050ff6743d69 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Tue, 5 Mar 2013 10:44:12 +0100 Subject: drm/nouveau/therm: do not make assumptions on temperature In nouveau_therm_sensor_event, temperature is stored as an uint8_t even though the original interface returns an int. This change should make it more obvious when the sensor is either very-ill-calibrated or when we selected the wrong sensor style on the nv40 family. Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index b37624af8297..0a17b9588e09 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -106,16 +106,16 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm, const char *thresolds[] = { "fanboost", "downclock", "critical", "shutdown" }; - uint8_t temperature = therm->temp_get(therm); + int temperature = therm->temp_get(therm); if (thrs < 0 || thrs > 3) return; if (dir == NOUVEAU_THERM_THRS_FALLING) - nv_info(therm, "temperature (%u C) went below the '%s' threshold\n", + nv_info(therm, "temperature (%i C) went below the '%s' threshold\n", temperature, thresolds[thrs]); else - nv_info(therm, "temperature (%u C) hit the '%s' threshold\n", + nv_info(therm, "temperature (%i C) hit the '%s' threshold\n", temperature, thresolds[thrs]); active = (dir == NOUVEAU_THERM_THRS_RISING); -- cgit v1.2.3 From c4ce9246ca4708482a9a03e76f4177e9f46a13ef Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Tue, 5 Mar 2013 10:58:59 +0100 Subject: drm/nouveau/therm: remove some confusion introduced by therm_mode The kernel message "[ PTHERM][0000:01:00.0] Thermal management: disabled" is misleading as it actually means "fan management: disabled". This patch fixes both the source and the message to improve readability. Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/include/subdev/therm.h | 2 +- drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 10 +++++----- drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | 2 +- drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index 6b17b614629f..0b20fc0d19c1 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -4,7 +4,7 @@ #include #include -enum nouveau_therm_mode { +enum nouveau_therm_fan_mode { NOUVEAU_THERM_CTRL_NONE = 0, NOUVEAU_THERM_CTRL_MANUAL = 1, NOUVEAU_THERM_CTRL_AUTO = 2, diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index f794dc89a3b2..321a55bc25a7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -134,7 +134,7 @@ nouveau_therm_alarm(struct nouveau_alarm *alarm) } int -nouveau_therm_mode(struct nouveau_therm *therm, int mode) +nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) { struct nouveau_therm_priv *priv = (void *)therm; struct nouveau_device *device = nv_device(therm); @@ -152,7 +152,7 @@ nouveau_therm_mode(struct nouveau_therm *therm, int mode) if (priv->mode == mode) return 0; - nv_info(therm, "Thermal management: %s\n", name[mode]); + nv_info(therm, "fan management: %s\n", name[mode]); nouveau_therm_update(therm, mode); return 0; } @@ -213,7 +213,7 @@ nouveau_therm_attr_set(struct nouveau_therm *therm, priv->fan->bios.max_duty = value; return 0; case NOUVEAU_THERM_ATTR_FAN_MODE: - return nouveau_therm_mode(therm, value); + return nouveau_therm_fan_mode(therm, value); case NOUVEAU_THERM_ATTR_THRS_FAN_BOOST: priv->bios_sensor.thrs_fan_boost.temp = value; priv->sensor.program_alarms(therm); @@ -263,7 +263,7 @@ _nouveau_therm_init(struct nouveau_object *object) return ret; if (priv->suspend >= 0) - nouveau_therm_mode(therm, priv->mode); + nouveau_therm_fan_mode(therm, priv->mode); priv->sensor.program_alarms(therm); return 0; } @@ -317,7 +317,7 @@ nouveau_therm_preinit(struct nouveau_therm *therm) nouveau_therm_sensor_ctor(therm); nouveau_therm_fan_ctor(therm); - nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_NONE); + nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 06b98706b3fc..d8483dd5e0f9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -102,7 +102,7 @@ struct nouveau_therm_priv { struct i2c_client *ic; }; -int nouveau_therm_mode(struct nouveau_therm *therm, int mode); +int nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode); int nouveau_therm_attr_get(struct nouveau_therm *therm, enum nouveau_therm_attr_type type); int nouveau_therm_attr_set(struct nouveau_therm *therm, diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index 0a17b9588e09..441f60bba226 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -123,7 +123,7 @@ void nouveau_therm_sensor_event(struct nouveau_therm *therm, case NOUVEAU_THERM_THRS_FANBOOST: if (active) { nouveau_therm_fan_set(therm, true, 100); - nouveau_therm_mode(therm, NOUVEAU_THERM_CTRL_AUTO); + nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO); } break; case NOUVEAU_THERM_THRS_DOWNCLOCK: -- cgit v1.2.3 From 13506e2ab40ebec3be3e2fda708d40d3ba972e3e Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Tue, 5 Mar 2013 11:24:04 +0100 Subject: drm/nouveau/therm-ic: the temperature is off by sensor_constant, warn the user Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 2 +- drivers/gpu/drm/nouveau/core/subdev/therm/ic.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index 321a55bc25a7..3f8083f41be8 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -313,8 +313,8 @@ nouveau_therm_create_(struct nouveau_object *parent, int nouveau_therm_preinit(struct nouveau_therm *therm) { - nouveau_therm_ic_ctor(therm); nouveau_therm_sensor_ctor(therm); + nouveau_therm_ic_ctor(therm); nouveau_therm_fan_ctor(therm); nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c index e24090bac195..8b3adec5fbb1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c @@ -32,6 +32,7 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, struct i2c_board_info *info) { struct nouveau_therm_priv *priv = (void *)nouveau_therm(i2c); + struct nvbios_therm_sensor *sensor = &priv->bios_sensor; struct i2c_client *client; request_module("%s%s", I2C_MODULE_PREFIX, info->type); @@ -46,8 +47,9 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, } nv_info(priv, - "Found an %s at address 0x%x (controlled by lm_sensors)\n", - info->type, info->addr); + "Found an %s at address 0x%x (controlled by lm_sensors, " + "temp offset %+i C)\n", + info->type, info->addr, sensor->offset_constant); priv->ic = client; return true; -- cgit v1.2.3 From ad40d73ef533ab0ad16b4a1ab2f7870c1f8ab954 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Thu, 14 Mar 2013 23:51:16 +0100 Subject: drm/nv40/therm: disable temperature reading if the bios misses some parameters Reported-by: Konrad Rzeszutek Wilk Tested-by: Konrad Rzeszutek Wilk Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | 10 ++++------ drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 9 --------- 2 files changed, 4 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index 0575af5328ec..c526d536409f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -93,12 +93,10 @@ nv40_temp_get(struct nouveau_therm *therm) } else return -ENODEV; - if (sensor->slope_div == 0) - sensor->slope_div = 1; - if (sensor->offset_den == 0) - sensor->offset_den = 1; - if (sensor->slope_mult < 1) - sensor->slope_mult = 1; + /* if the slope or the offset is unset, do no use the sensor */ + if (!sensor->slope_div || !sensor->slope_mult || + !sensor->offset_num || !sensor->offset_den) + return -ENODEV; core_temp = core_temp * sensor->slope_mult / sensor->slope_div; core_temp = core_temp + sensor->offset_num / sensor->offset_den; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index 441f60bba226..0d94d1a19eb7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -34,10 +34,6 @@ nouveau_therm_temp_set_defaults(struct nouveau_therm *therm) { struct nouveau_therm_priv *priv = (void *)therm; - priv->bios_sensor.slope_mult = 1; - priv->bios_sensor.slope_div = 1; - priv->bios_sensor.offset_num = 0; - priv->bios_sensor.offset_den = 1; priv->bios_sensor.offset_constant = 0; priv->bios_sensor.thrs_fan_boost.temp = 90; @@ -60,11 +56,6 @@ nouveau_therm_temp_safety_checks(struct nouveau_therm *therm) struct nouveau_therm_priv *priv = (void *)therm; struct nvbios_therm_sensor *s = &priv->bios_sensor; - if (!priv->bios_sensor.slope_div) - priv->bios_sensor.slope_div = 1; - if (!priv->bios_sensor.offset_den) - priv->bios_sensor.offset_den = 1; - /* enforce a minimum hysteresis on thresholds */ s->thrs_fan_boost.hysteresis = max_t(u8, s->thrs_fan_boost.hysteresis, 2); s->thrs_down_clock.hysteresis = max_t(u8, s->thrs_down_clock.hysteresis, 2); -- cgit v1.2.3 From 76c0295c389ad9ba19b668b5974cdd90eb95788e Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Fri, 15 Mar 2013 02:09:20 +0100 Subject: drm/nv40/therm: reserve negative temperatures for errors Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c index c526d536409f..a70d1b7e397b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv40.c @@ -102,6 +102,10 @@ nv40_temp_get(struct nouveau_therm *therm) core_temp = core_temp + sensor->offset_num / sensor->offset_den; core_temp = core_temp + sensor->offset_constant - 8; + /* reserve negative temperatures for errors */ + if (core_temp < 0) + core_temp = 0; + return core_temp; } -- cgit v1.2.3 From 98ee7c7c63f16e443f51abf08e5412f8eb44ad1e Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Fri, 15 Mar 2013 00:21:07 +0100 Subject: drm/nouveau/therm: disable auto fan management if temperature is not available Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index 3f8083f41be8..d6a05589c941 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -149,6 +149,11 @@ nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0)) return -EINVAL; + /* do not allow automatic fan management if the thermal sensor is + * not available */ + if (priv->mode == 2 && therm->temp_get(therm) < 0) + return -EINVAL; + if (priv->mode == mode) return 0; -- cgit v1.2.3 From bf55eb843d266ad31696f17cf1f5c237409485cf Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Fri, 15 Mar 2013 00:42:38 +0100 Subject: drm/nouveau/therm: disable temperature management if the sensor isn't readable Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index 0d94d1a19eb7..2a02c9f1d7ff 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -193,7 +193,7 @@ alarm_timer_callback(struct nouveau_alarm *alarm) NOUVEAU_THERM_THRS_SHUTDOWN); /* schedule the next poll in one second */ - if (list_empty(&alarm->head)) + if (therm->temp_get(therm) >= 0 && list_empty(&alarm->head)) ptimer->alarm(ptimer, 1000 * 1000 * 1000, alarm); spin_unlock_irqrestore(&priv->sensor.alarm_program_lock, flags); -- cgit v1.2.3 From 0b3ee3772e11da2f36c91e542545780d3ed28415 Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Fri, 15 Mar 2013 01:47:16 +0100 Subject: drm/nouveau/therm: display the availability of the internal sensor Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/subdev/therm/base.c | 1 + drivers/gpu/drm/nouveau/core/subdev/therm/priv.h | 1 + drivers/gpu/drm/nouveau/core/subdev/therm/temp.c | 11 +++++++++++ 3 files changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index d6a05589c941..a00a5a76e2d6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -323,6 +323,7 @@ nouveau_therm_preinit(struct nouveau_therm *therm) nouveau_therm_fan_ctor(therm); nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE); + nouveau_therm_sensor_preinit(therm); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index d8483dd5e0f9..438d9824b774 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -122,6 +122,7 @@ int nouveau_therm_fan_sense(struct nouveau_therm *therm); int nouveau_therm_preinit(struct nouveau_therm *); +void nouveau_therm_sensor_preinit(struct nouveau_therm *); void nouveau_therm_sensor_set_threshold_state(struct nouveau_therm *therm, enum nouveau_therm_thrs thrs, enum nouveau_therm_thrs_state st); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index 2a02c9f1d7ff..470f6a47b656 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -216,6 +216,17 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm) alarm_timer_callback(&priv->sensor.therm_poll_alarm); } +void +nouveau_therm_sensor_preinit(struct nouveau_therm *therm) +{ + const char *sensor_avail = "yes"; + + if (therm->temp_get(therm) < 0) + sensor_avail = "no"; + + nv_info(therm, "internal sensor: %s\n", sensor_avail); +} + int nouveau_therm_sensor_ctor(struct nouveau_therm *therm) { -- cgit v1.2.3 From 804ca90f3fe35dd7c12889eaa74a44abbc4b91fd Mon Sep 17 00:00:00 2001 From: Martin Peres Date: Fri, 15 Mar 2013 00:59:55 +0100 Subject: drm/nouveau/hwmon: do not expose a buggy temperature if it is unavailable Signed-off-by: Martin Peres Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_pm.c | 44 +++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index bb54098c6d97..936b442a6ab7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -402,8 +402,12 @@ nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) struct drm_device *dev = dev_get_drvdata(d); struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_therm *therm = nouveau_therm(drm->device); + int temp = therm->temp_get(therm); - return snprintf(buf, PAGE_SIZE, "%d\n", therm->temp_get(therm) * 1000); + if (temp < 0) + return temp; + + return snprintf(buf, PAGE_SIZE, "%d\n", temp * 1000); } static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, nouveau_hwmon_show_temp, NULL, 0); @@ -871,7 +875,12 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR, nouveau_hwmon_get_pwm1_max, nouveau_hwmon_set_pwm1_max, 0); -static struct attribute *hwmon_attributes[] = { +static struct attribute *hwmon_default_attributes[] = { + &sensor_dev_attr_name.dev_attr.attr, + &sensor_dev_attr_update_rate.dev_attr.attr, + NULL +}; +static struct attribute *hwmon_temp_attributes[] = { &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_temp1_auto_point1_pwm.dev_attr.attr, &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, @@ -882,8 +891,6 @@ static struct attribute *hwmon_attributes[] = { &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr, &sensor_dev_attr_temp1_emergency.dev_attr.attr, &sensor_dev_attr_temp1_emergency_hyst.dev_attr.attr, - &sensor_dev_attr_name.dev_attr.attr, - &sensor_dev_attr_update_rate.dev_attr.attr, NULL }; static struct attribute *hwmon_fan_rpm_attributes[] = { @@ -898,8 +905,11 @@ static struct attribute *hwmon_pwm_fan_attributes[] = { NULL }; -static const struct attribute_group hwmon_attrgroup = { - .attrs = hwmon_attributes, +static const struct attribute_group hwmon_default_attrgroup = { + .attrs = hwmon_default_attributes, +}; +static const struct attribute_group hwmon_temp_attrgroup = { + .attrs = hwmon_temp_attributes, }; static const struct attribute_group hwmon_fan_rpm_attrgroup = { .attrs = hwmon_fan_rpm_attributes, @@ -931,13 +941,22 @@ nouveau_hwmon_init(struct drm_device *dev) } dev_set_drvdata(hwmon_dev, dev); - /* default sysfs entries */ - ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_attrgroup); + /* set the default attributes */ + ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_default_attrgroup); if (ret) { if (ret) goto error; } + /* if the card has a working thermal sensor */ + if (therm->temp_get(therm) >= 0) { + ret = sysfs_create_group(&hwmon_dev->kobj, &hwmon_temp_attrgroup); + if (ret) { + if (ret) + goto error; + } + } + /* if the card has a pwm fan */ /*XXX: incorrect, need better detection for this, some boards have * the gpio entries for pwm fan control even when there's no @@ -979,11 +998,10 @@ nouveau_hwmon_fini(struct drm_device *dev) struct nouveau_pm *pm = nouveau_pm(dev); if (pm->hwmon) { - sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, - &hwmon_pwm_fan_attrgroup); - sysfs_remove_group(&pm->hwmon->kobj, - &hwmon_fan_rpm_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_default_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_temp_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_pwm_fan_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_fan_rpm_attrgroup); hwmon_device_unregister(pm->hwmon); } -- cgit v1.2.3 From 06d9db7273c7bd5b07624b313faeea57a4b31056 Mon Sep 17 00:00:00 2001 From: Kishon Vijay Abraham I Date: Fri, 15 Mar 2013 18:58:50 +0530 Subject: usb: musb: gadget: do *unmap_dma_buffer* only for valid DMA addr musb does not use DMA buffer for ep0 but it uses the same giveback function *musb_g_giveback* for all endpoints (*musb_g_ep0_giveback* calls *musb_g_giveback*). So for ep0 case request.dma will be '0' and will result in kernel OOPS if tried to *unmap_dma_buffer* for requests in ep0. Fixed it by doing *unmap_dma_buffer* only for valid DMA addr and checking that musb_ep->dma is valid when unmapping. Signed-off-by: Kishon Vijay Abraham I Signed-off-by: Felipe Balbi --- drivers/usb/musb/musb_gadget.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index be18537c5f14..83eddedcd9be 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -141,7 +141,9 @@ static inline void map_dma_buffer(struct musb_request *request, static inline void unmap_dma_buffer(struct musb_request *request, struct musb *musb) { - if (!is_buffer_mapped(request)) + struct musb_ep *musb_ep = request->ep; + + if (!is_buffer_mapped(request) || !musb_ep->dma) return; if (request->request.dma == DMA_ADDR_INVALID) { @@ -195,7 +197,10 @@ __acquires(ep->musb->lock) ep->busy = 1; spin_unlock(&musb->lock); - unmap_dma_buffer(req, musb); + + if (!dma_mapping_error(&musb->g.dev, request->dma)) + unmap_dma_buffer(req, musb); + if (request->status == 0) dev_dbg(musb->controller, "%s done request %p, %d/%d\n", ep->end_point.name, request, -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 9d1a455b0ca1c2c956b4d9ab212864a8695270f1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Mar 2013 11:25:36 +0100 Subject: drm/i915: Use the fixed pixel clock for eDP in intel_dp_set_m_n() The eDP output on HP Z1 is still broken when X is started even after fixing the infinite link-train loop. The regression was introduced in 3.6 kernel for cleaning up the mode clock handling code in intel_dp.c by the commit [71244653: drm/i915: adjusted_mode->clock in the dp mode_fix]. In the past, the clock of the reference mode was modified in intel_dp_mode_fixup() in the case of eDP fixed clock, and this clock was used for calculating in intel_dp_set_m_n(). This override was removed, thus the wrong mode clock is used for the calculation, resulting in a psychedelic smoking output in the end. This patch corrects the clock to be used in the place. v1->v2: Use intel_edp_target_clock() for checking eDP fixed clock instead of open code as in ironlake_set_m_n(). Cc: Signed-off-by: Takashi Iwai Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_dp.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index d46dde5a51e3..d7d4afe01341 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -820,6 +820,7 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, struct intel_link_m_n m_n; int pipe = intel_crtc->pipe; enum transcoder cpu_transcoder = intel_crtc->cpu_transcoder; + int target_clock; /* * Find the lane count in the intel_encoder private @@ -835,13 +836,22 @@ intel_dp_set_m_n(struct drm_crtc *crtc, struct drm_display_mode *mode, } } + target_clock = mode->clock; + for_each_encoder_on_crtc(dev, crtc, intel_encoder) { + if (intel_encoder->type == INTEL_OUTPUT_EDP) { + target_clock = intel_edp_target_clock(intel_encoder, + mode); + break; + } + } + /* * Compute the GMCH and Link ratios. The '3' here is * the number of bytes_per_pixel post-LUT, which we always * set up for 8-bits of R/G/B, or 3 bytes total. */ intel_link_compute_m_n(intel_crtc->bpp, lane_count, - mode->clock, adjusted_mode->clock, &m_n); + target_clock, adjusted_mode->clock, &m_n); if (IS_HASWELL(dev)) { I915_WRITE(PIPE_DATA_M1(cpu_transcoder), -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 3d464d9b71ef2f2b40a4bc9dcf06794fd1be9d12 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 18 Mar 2013 09:45:42 -0400 Subject: HID: usbhid: quirk for Realtek Multi-card reader This device needs to be added to the quirks list with HID_QUIRK_NO_INIT_REPORTS, otherwise it causes 10 seconds timeout during report initialization. This fixes Red Hat bugzilla https://bugzilla.redhat.com/show_bug.cgi?id=806587 Cc: stable@vger.kernel.org Signed-off-by: Josh Boyer Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 6e5c2ffa8d96..3fc5c33561d5 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -681,6 +681,9 @@ #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001 0x3001 #define USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008 0x3008 +#define USB_VENDOR_ID_REALTEK 0x0bda +#define USB_DEVICE_ID_REALTEK_READER 0x0152 + #define USB_VENDOR_ID_ROCCAT 0x1e7d #define USB_DEVICE_ID_ROCCAT_ARVO 0x30d4 #define USB_DEVICE_ID_ROCCAT_ISKU 0x319c diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index e0e6abf1cd3b..e991d81602b6 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -80,6 +80,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PRODIGE, USB_DEVICE_ID_PRODIGE_CORDLESS, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3001, HID_QUIRK_NOGET }, { USB_VENDOR_ID_QUANTA, USB_DEVICE_ID_QUANTA_OPTICAL_TOUCH_3008, HID_QUIRK_NOGET }, + { USB_VENDOR_ID_REALTEK, USB_DEVICE_ID_REALTEK_READER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_SENNHEISER, USB_DEVICE_ID_SENNHEISER_BTD500USB, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SIGMATEL, USB_DEVICE_ID_SIGMATEL_STMP3780, HID_QUIRK_NOGET }, { USB_VENDOR_ID_SUN, USB_DEVICE_ID_RARITAN_KVM_DONGLE, HID_QUIRK_NOGET }, -- cgit v1.2.3 From 620ae90ed8ca8b6e40cb9e10279b4f5ef9f0ab81 Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Mon, 18 Mar 2013 09:47:02 -0400 Subject: HID: usbhid: quirk for MSI GX680R led panel This keyboard backlight device causes a 10 second delay to boot. Add it to the quirk list with HID_QUIRK_NO_INIT_REPORTS. This fixes Red Hat bugzilla https://bugzilla.redhat.com/show_bug.cgi?id=907221 Cc: stable@vger.kernel.org Signed-off-by: Josh Boyer Signed-off-by: Jiri Kosina --- drivers/hid/hid-ids.h | 3 +++ drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3fc5c33561d5..49b88a0608fb 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -587,6 +587,9 @@ #define USB_VENDOR_ID_MONTEREY 0x0566 #define USB_DEVICE_ID_GENIUS_KB29E 0x3004 +#define USB_VENDOR_ID_MSI 0x1770 +#define USB_DEVICE_ID_MSI_GX680R_LED_PANEL 0xff00 + #define USB_VENDOR_ID_NATIONAL_SEMICONDUCTOR 0x0400 #define USB_DEVICE_ID_N_S_HARMONY 0xc359 diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index e991d81602b6..476c984dbdf3 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -73,6 +73,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, + { USB_VENDIR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, -- cgit v1.2.3 From 570637dc8eeb2faba06228d497ff40bb019bcc93 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Mon, 18 Mar 2013 15:50:10 +0100 Subject: HID: usbhid: fix build problem Fix build problem caused by typo introduced by 620ae90ed8 ("HID: usbhid: quirk for MSI GX680R led panel"). Reported-by: fengguang.wu@intel.com Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 476c984dbdf3..19b8360f2330 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -73,7 +73,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_FORMOSA, USB_DEVICE_ID_FORMOSA_IR_RECEIVER, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_FREESCALE, USB_DEVICE_ID_FREESCALE_MX28, HID_QUIRK_NOGET }, { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_NOGET }, - { USB_VENDIR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, + { USB_VENDOR_ID_MSI, USB_DEVICE_ID_MSI_GX680R_LED_PANEL, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_NOVATEK, USB_DEVICE_ID_NOVATEK_MOUSE, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN, HID_QUIRK_NO_INIT_REPORTS }, { USB_VENDOR_ID_PIXART, USB_DEVICE_ID_PIXART_OPTICAL_TOUCH_SCREEN1, HID_QUIRK_NO_INIT_REPORTS }, -- cgit v1.2.3 From f8264340e694604863255cc0276491d17c402390 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Mon, 25 Feb 2013 10:56:01 -0800 Subject: USB: xhci - fix bit definitions for IMAN register According to XHCI specification (5.5.2.1) the IP is bit 0 and IE is bit 1 of IMAN register. Previously their definitions were reversed. Even though there are no ill effects being observed from the swapped definitions (because IMAN_IP is RW1C and in legacy PCI case we come in with it already set to 1 so it was clearing itself even though we were setting IMAN_IE instead of IMAN_IP), we should still correct the values. This patch should be backported to kernels as old as 2.6.36, that contain the commit 4e833c0b87a30798e67f06120cecebef6ee9644c "xhci: don't re-enable IE constantly". Signed-off-by: Dmitry Torokhov Signed-off-by: Sarah Sharp Cc: stable@vger.kernel.org --- drivers/usb/host/xhci.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index f791bd0aee6c..2c510e4a7d4c 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -206,8 +206,8 @@ struct xhci_op_regs { /* bits 12:31 are reserved (and should be preserved on writes). */ /* IMAN - Interrupt Management Register */ -#define IMAN_IP (1 << 1) -#define IMAN_IE (1 << 0) +#define IMAN_IE (1 << 1) +#define IMAN_IP (1 << 0) /* USBSTS - USB status - status bitmasks */ /* HC not running - set to 1 when run/stop bit is cleared. */ -- cgit v1.2.3 From b009aac12cd0fe34293c68af8ac48b85be3bd858 Mon Sep 17 00:00:00 2001 From: Maciej Å»enczykowski Date: Fri, 15 Mar 2013 11:56:17 +0000 Subject: bnx2x: fix occasional statistics off-by-4GB error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The UPDATE_QSTAT function introduced on February 15, 2012 in commit 1355b704b9ba "bnx2x: consistent statistics after internal driver reload" incorrectly fails to handle overflow during addition of the lower 32-bit field of a stat. This bug is present since 3.4-rc1 and should thus be considered a candidate for stable 3.4+ releases. Google-Bug-Id: 8374428 Signed-off-by: Maciej Å»enczykowski Cc: Mintz Yuval Acked-by: Eilon Greenstein Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h index 364e37ecbc5c..198f6f1c9ad5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.h @@ -459,8 +459,9 @@ struct bnx2x_fw_port_stats_old { #define UPDATE_QSTAT(s, t) \ do { \ - qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi); \ qstats->t##_lo = qstats_old->t##_lo + le32_to_cpu(s.lo); \ + qstats->t##_hi = qstats_old->t##_hi + le32_to_cpu(s.hi) \ + + ((qstats->t##_lo < qstats_old->t##_lo) ? 1 : 0); \ } while (0) #define UPDATE_QSTAT_OLD(f) \ -- cgit v1.2.3 From ebaf5795ef57a70a042ea259448a465024e2821d Mon Sep 17 00:00:00 2001 From: Ming Lei Date: Mon, 18 Mar 2013 23:45:11 +0800 Subject: Bluetooth: Add support for Dell[QCA 0cf3:817a] Add support for the AR9462 chip T: Bus=03 Lev=01 Prnt=01 Port=08 Cnt=01 Dev#= 5 Spd=12 MxCh= 0 D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 P: Vendor=0cf3 ProdID=817a Rev= 0.02 C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms Cc: Cc: Gustavo Padovan Signed-off-by: Ming Lei Signed-off-by: Gustavo Padovan --- drivers/bluetooth/ath3k.c | 2 ++ drivers/bluetooth/btusb.c | 1 + 2 files changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 0a6ef6b694d4..8af01c177ce5 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -77,6 +77,7 @@ static struct usb_device_id ath3k_table[] = { { USB_DEVICE(0x0CF3, 0x3004) }, { USB_DEVICE(0x0CF3, 0x3008) }, { USB_DEVICE(0x0CF3, 0x311D) }, + { USB_DEVICE(0x0CF3, 0x817a) }, { USB_DEVICE(0x13d3, 0x3375) }, { USB_DEVICE(0x04CA, 0x3004) }, { USB_DEVICE(0x04CA, 0x3005) }, @@ -112,6 +113,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311D), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0CF3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index 11ac3036bb8a..2cc5f774a29c 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c @@ -135,6 +135,7 @@ static struct usb_device_id blacklist_table[] = { { USB_DEVICE(0x0cf3, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x3008), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x0cf3, 0x311d), .driver_info = BTUSB_ATH3012 }, + { USB_DEVICE(0x0cf3, 0x817a), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x13d3, 0x3375), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, -- cgit v1.2.3 From 7f42ace3118afedbd1848a349d01a11d9ca13d41 Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Thu, 14 Mar 2013 12:48:40 +0100 Subject: iwl3945: fix length of dma buffers commit bdb084b22d8aee66c87af5e9c36bd6cf7f3bccfd Author: Stanislaw Gruszka Date: Wed Feb 13 15:49:08 2013 +0100 iwlegacy: more checks for dma mapping errors broke il3945_tx_skb() dma buffer length settings, what results on firmware errors like showed below and make 3945 device non usable. iwl3945 0000:02:00.0: Microcode SW error detected. Restarting 0x82000008. iwl3945 0000:02:00.0: Loaded firmware version: 15.32.2.9 iwl3945 0000:02:00.0: Start IWL Error Log Dump: iwl3945 0000:02:00.0: Status: 0x000202E4, count: 1 iwl3945 0000:02:00.0: Desc Time asrtPC blink2 ilink1 nmiPC Line iwl3945 0000:02:00.0: SYSASSERT (0x5) 0000208934 0x008B6 0x0035E 0x00320 0x00000 267 iwl3945 0000:02:00.0: Error Reply type 0x00000001 cmd Reported-by: Zdenek Kabelac Reported-by: Krzysztof Kolasa Reported-by: Pedro Francisco Signed-off-by: Stanislaw Gruszka Signed-off-by: John W. Linville --- drivers/net/wireless/iwlegacy/3945-mac.c | 22 ++++++++++++---------- 1 file changed, 12 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..c353b5f19c8c 100644 --- a/drivers/net/wireless/iwlegacy/3945-mac.c +++ b/drivers/net/wireless/iwlegacy/3945-mac.c @@ -475,6 +475,7 @@ il3945_tx_skb(struct il_priv *il, dma_addr_t txcmd_phys; int txq_id = skb_get_queue_mapping(skb); u16 len, idx, hdr_len; + u16 firstlen, secondlen; u8 id; u8 unicast; u8 sta_id; @@ -589,21 +590,22 @@ il3945_tx_skb(struct il_priv *il, len = sizeof(struct il3945_tx_cmd) + sizeof(struct il_cmd_header) + hdr_len; - len = (len + 3) & ~3; + firstlen = (len + 3) & ~3; /* Physical address of this Tx command's header (not MAC header!), * within command buffer array. */ txcmd_phys = - pci_map_single(il->pci_dev, &out_cmd->hdr, len, PCI_DMA_TODEVICE); + pci_map_single(il->pci_dev, &out_cmd->hdr, firstlen, + PCI_DMA_TODEVICE); if (unlikely(pci_dma_mapping_error(il->pci_dev, txcmd_phys))) goto drop_unlock; /* Set up TFD's 2nd entry to point directly to remainder of skb, * if any (802.11 null frames have no payload). */ - len = skb->len - hdr_len; - if (len) { + secondlen = skb->len - hdr_len; + if (secondlen > 0) { phys_addr = - pci_map_single(il->pci_dev, skb->data + hdr_len, len, + pci_map_single(il->pci_dev, skb->data + hdr_len, secondlen, PCI_DMA_TODEVICE); if (unlikely(pci_dma_mapping_error(il->pci_dev, phys_addr))) goto drop_unlock; @@ -611,12 +613,12 @@ il3945_tx_skb(struct il_priv *il, /* Add buffer containing Tx command and MAC(!) header to TFD's * first entry */ - il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, len, 1, 0); + il->ops->txq_attach_buf_to_tfd(il, txq, txcmd_phys, firstlen, 1, 0); dma_unmap_addr_set(out_meta, mapping, txcmd_phys); - dma_unmap_len_set(out_meta, len, len); - if (len) - il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, len, 0, - U32_PAD(len)); + dma_unmap_len_set(out_meta, len, firstlen); + if (secondlen > 0) + il->ops->txq_attach_buf_to_tfd(il, txq, phys_addr, secondlen, 0, + U32_PAD(secondlen)); if (!ieee80211_has_morefrags(hdr->frame_control)) { txq->need_update = 1; -- cgit v1.2.3 From 74632d11a133b5baf6b9d622dd19d2f944d93d94 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Mar 2013 14:53:31 +0100 Subject: ath9k_hw: revert chainmask to user configuration after calibration The commit 'ath9k_hw: fix calibration issues on chainmask that don't include chain 0' changed the hardware chainmask to the chip chainmask for the duration of the calibration, but the revert to user configuration in the reset path runs too early. That causes some issues with limiting the number of antennas (including spurious failure in hardware-generated packets). Fix this by reverting the chainmask after the essential parts of the calibration that need the workaround, and before NF calibration is run. Signed-off-by: Felix Fietkau Reported-by: Wojciech Dubowik Tested-by: Wojciech Dubowik Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/ar9003_calib.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c index 4cc13940c895..f76c3ca07a45 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c @@ -1023,6 +1023,7 @@ static bool ar9003_hw_init_cal(struct ath_hw *ah, AR_PHY_AGC_CONTROL_FLTR_CAL | AR_PHY_AGC_CONTROL_PKDET_CAL; + /* Use chip chainmask only for calibration */ ar9003_hw_set_chain_masks(ah, ah->caps.rx_chainmask, ah->caps.tx_chainmask); if (rtt) { @@ -1150,6 +1151,9 @@ skip_tx_iqcal: ar9003_hw_rtt_disable(ah); } + /* Revert chainmask to runtime parameters */ + ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); + /* Initialize list pointers */ ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL; -- cgit v1.2.3 From 01d4ab96d2e7fceaad204e5a8710ce34e229b8c5 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 15 Mar 2013 16:18:44 +0100 Subject: ath9k: limit tx path hang check to normal data queues The beacon and multicast-buffer queues are managed by the beacon tasklet, and the generic tx path hang check does not help in any way here. Running it on those queues anyway can introduce some race conditions leading to unnecessary chip resets. Cc: stable@vger.kernel.org Signed-off-by: Felix Fietkau Signed-off-by: John W. Linville --- drivers/net/wireless/ath/ath9k/link.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath/ath9k/link.c b/drivers/net/wireless/ath/ath9k/link.c index ade3afb21f91..39c84ecf6a42 100644 --- a/drivers/net/wireless/ath/ath9k/link.c +++ b/drivers/net/wireless/ath/ath9k/link.c @@ -28,21 +28,21 @@ void ath_tx_complete_poll_work(struct work_struct *work) int i; bool needreset = false; - for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) - if (ATH_TXQ_SETUP(sc, i)) { - txq = &sc->tx.txq[i]; - ath_txq_lock(sc, txq); - if (txq->axq_depth) { - if (txq->axq_tx_inprogress) { - needreset = true; - ath_txq_unlock(sc, txq); - break; - } else { - txq->axq_tx_inprogress = true; - } + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + txq = sc->tx.txq_map[i]; + + ath_txq_lock(sc, txq); + if (txq->axq_depth) { + if (txq->axq_tx_inprogress) { + needreset = true; + ath_txq_unlock(sc, txq); + break; + } else { + txq->axq_tx_inprogress = true; } - ath_txq_unlock_complete(sc, txq); } + ath_txq_unlock_complete(sc, txq); + } if (needreset) { ath_dbg(ath9k_hw_common(sc->sc_ah), RESET, -- cgit v1.2.3 From 00d7ea11ff0783e24fe70778f3141270b561aaa1 Mon Sep 17 00:00:00 2001 From: Amitkumar Karwar Date: Fri, 15 Mar 2013 18:47:05 -0700 Subject: mwifiex: fix race when queuing commands Running the following script repeatedly on XO-4 with SD8787 produces command timeout and system lockup. insmod mwifiex_sdio.ko sleep 1 ifconfig eth0 up iwlist eth0 scan & sleep 0.5 rmmod mwifiex_sdio mwifiex_send_cmd_async() is called for sync as well as async commands. (mwifiex_send_cmd_sync() internally calls it for sync command.) "adapter->cmd_queued" gets filled inside mwifiex_send_cmd_async() routine for both types of commands. But it is used only for sync commands in mwifiex_wait_queue_complete(). This could lead to a race when two threads try to queue a sync command with another sync/async command simultaneously. Get rid of global variable and pass command node as a parameter to mwifiex_wait_queue_complete() to fix the problem. Cc: # 3.8 Reported-by: Daniel Drake Tested-by: Daniel Drake Tested-by: Marco Cesarano Signed-off-by: Amitkumar Karwar Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 5 ++--- drivers/net/wireless/mwifiex/main.h | 4 ++-- drivers/net/wireless/mwifiex/scan.c | 8 ++++---- drivers/net/wireless/mwifiex/sta_ioctl.c | 10 ++-------- 4 files changed, 10 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 20a6c5555873..2ffabddbcfca 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -484,8 +484,6 @@ int mwifiex_send_cmd_sync(struct mwifiex_private *priv, uint16_t cmd_no, ret = mwifiex_send_cmd_async(priv, cmd_no, cmd_action, cmd_oid, data_buf); - if (!ret) - ret = mwifiex_wait_queue_complete(adapter); return ret; } @@ -588,9 +586,10 @@ int mwifiex_send_cmd_async(struct mwifiex_private *priv, uint16_t cmd_no, if (cmd_no == HostCmd_CMD_802_11_SCAN) { mwifiex_queue_scan_cmd(priv, cmd_node); } else { - adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); queue_work(adapter->workqueue, &adapter->main_work); + if (cmd_node->wait_q_enabled) + ret = mwifiex_wait_queue_complete(adapter, cmd_node); } return ret; diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h index 553adfb0aa81..7035ade9af74 100644 --- a/drivers/net/wireless/mwifiex/main.h +++ b/drivers/net/wireless/mwifiex/main.h @@ -723,7 +723,6 @@ struct mwifiex_adapter { u16 cmd_wait_q_required; struct mwifiex_wait_queue cmd_wait_q; u8 scan_wait_q_woken; - struct cmd_ctrl_node *cmd_queued; spinlock_t queue_lock; /* lock for tx queues */ struct completion fw_load; u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; @@ -1018,7 +1017,8 @@ int mwifiex_request_set_multicast_list(struct mwifiex_private *priv, struct mwifiex_multicast_list *mcast_list); int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, struct net_device *dev); -int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter); +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_queued); int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss, struct cfg80211_ssid *req_ssid); int mwifiex_cancel_hs(struct mwifiex_private *priv, int cmd_type); diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index bb60c2754a97..d215b4d3c51b 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c @@ -1388,10 +1388,13 @@ int mwifiex_scan_networks(struct mwifiex_private *priv, list_del(&cmd_node->list); spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); - adapter->cmd_queued = cmd_node; mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true); queue_work(adapter->workqueue, &adapter->main_work); + + /* Perform internal scan synchronously */ + if (!priv->scan_request) + mwifiex_wait_queue_complete(adapter, cmd_node); } else { spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); @@ -1946,9 +1949,6 @@ int mwifiex_request_scan(struct mwifiex_private *priv, /* Normal scan */ ret = mwifiex_scan_networks(priv, NULL); - if (!ret) - ret = mwifiex_wait_queue_complete(priv->adapter); - up(&priv->async_sem); return ret; diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c index 9f33c92c90f5..13100f8de3db 100644 --- a/drivers/net/wireless/mwifiex/sta_ioctl.c +++ b/drivers/net/wireless/mwifiex/sta_ioctl.c @@ -54,16 +54,10 @@ int mwifiex_copy_mcast_addr(struct mwifiex_multicast_list *mlist, * This function waits on a cmd wait queue. It also cancels the pending * request after waking up, in case of errors. */ -int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter) +int mwifiex_wait_queue_complete(struct mwifiex_adapter *adapter, + struct cmd_ctrl_node *cmd_queued) { int status; - struct cmd_ctrl_node *cmd_queued; - - if (!adapter->cmd_queued) - return 0; - - cmd_queued = adapter->cmd_queued; - adapter->cmd_queued = NULL; dev_dbg(adapter->dev, "cmd pending\n"); atomic_inc(&adapter->cmd_pending); -- cgit v1.2.3 From a3e240cacc93a06bff3313e28938e980d01a2160 Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Fri, 15 Mar 2013 18:47:06 -0700 Subject: mwifiex: skip pending commands after function shutdown During rmmod mwifiex_sdio processing FUNC_SHUTDOWN command is sent to firmware. Firmware expcets only FUNC_INIT once WLAN function is shut down. Any command pending in the command queue should be ignored and freed. Cc: # 3.8 Tested-by: Daniel Drake Tested-by: Marco Cesarano Signed-off-by: Bing Zhao Signed-off-by: Amitkumar Karwar Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/cmdevt.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c index 2ffabddbcfca..b5c8b962ce12 100644 --- a/drivers/net/wireless/mwifiex/cmdevt.c +++ b/drivers/net/wireless/mwifiex/cmdevt.c @@ -157,6 +157,20 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, return -1; } + cmd_code = le16_to_cpu(host_cmd->command); + cmd_size = le16_to_cpu(host_cmd->size); + + if (adapter->hw_status == MWIFIEX_HW_STATUS_RESET && + cmd_code != HostCmd_CMD_FUNC_SHUTDOWN && + cmd_code != HostCmd_CMD_FUNC_INIT) { + dev_err(adapter->dev, + "DNLD_CMD: FW in reset state, ignore cmd %#x\n", + cmd_code); + mwifiex_complete_cmd(adapter, cmd_node); + mwifiex_insert_cmd_to_free_q(adapter, cmd_node); + return -1; + } + /* Set command sequence number */ adapter->seq_num++; host_cmd->seq_num = cpu_to_le16(HostCmd_SET_SEQ_NO_BSS_INFO @@ -168,9 +182,6 @@ static int mwifiex_dnld_cmd_to_fw(struct mwifiex_private *priv, adapter->curr_cmd = cmd_node; spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); - cmd_code = le16_to_cpu(host_cmd->command); - cmd_size = le16_to_cpu(host_cmd->size); - /* Adjust skb length */ if (cmd_node->cmd_skb->len > cmd_size) /* -- cgit v1.2.3 From 084c7189acb3f969c855536166042e27f5dd703f Mon Sep 17 00:00:00 2001 From: Bing Zhao Date: Fri, 15 Mar 2013 18:47:07 -0700 Subject: mwifiex: cancel cmd timer and free curr_cmd in shutdown process curr_cmd points to the command that is in processing or waiting for its command response from firmware. If the function shutdown happens to occur at this time we should cancel the cmd timer and put the command back to free queue. Cc: # 3.8 Tested-by: Marco Cesarano Signed-off-by: Bing Zhao Signed-off-by: John W. Linville --- drivers/net/wireless/mwifiex/init.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c index e38aa9b3663d..0ff4c37ab42a 100644 --- a/drivers/net/wireless/mwifiex/init.c +++ b/drivers/net/wireless/mwifiex/init.c @@ -709,6 +709,14 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter) return ret; } + /* cancel current command */ + if (adapter->curr_cmd) { + dev_warn(adapter->dev, "curr_cmd is still in processing\n"); + del_timer(&adapter->cmd_timer); + mwifiex_insert_cmd_to_free_q(adapter, adapter->curr_cmd); + adapter->curr_cmd = NULL; + } + /* shut down mwifiex */ dev_dbg(adapter->dev, "info: shutdown mwifiex...\n"); -- cgit v1.2.3 From 36ef0b473fbf43d5db23eea4616cc1d18cec245f Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sun, 17 Mar 2013 11:54:04 +0200 Subject: rtlwifi: usb: add missing freeing of skbuff Signed-off-by: Jussi Kivilinna Acked-by: Larry Finger Cc: stable@vger.kernel.org Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c index 156b52732f3d..5847d6d0881e 100644 --- a/drivers/net/wireless/rtlwifi/usb.c +++ b/drivers/net/wireless/rtlwifi/usb.c @@ -851,6 +851,7 @@ static void _rtl_usb_transmit(struct ieee80211_hw *hw, struct sk_buff *skb, if (unlikely(!_urb)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't allocate urb. Drop skb!\n"); + kfree_skb(skb); return; } _rtl_submit_tx_urb(hw, _urb); -- cgit v1.2.3 From 882e3f8e6966109ad837cfe79e97cf3deb3ae19b Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Mon, 4 Mar 2013 14:08:06 +0100 Subject: target_core_sbc: use noop for SYNCHRONIZE_CACHE Windows does not expect SYNCHRONIZE_CACHE to be not supported, and will generate a BSOD upon shutdown when using rd_mcp backend. So better use a noop here. Signed-off-by: Hannes Reinecke Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_sbc.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_sbc.c b/drivers/target/target_core_sbc.c index 290230de2c53..60d4b5185f32 100644 --- a/drivers/target/target_core_sbc.c +++ b/drivers/target/target_core_sbc.c @@ -464,8 +464,11 @@ sbc_parse_cdb(struct se_cmd *cmd, struct sbc_ops *ops) break; case SYNCHRONIZE_CACHE: case SYNCHRONIZE_CACHE_16: - if (!ops->execute_sync_cache) - return TCM_UNSUPPORTED_SCSI_OPCODE; + if (!ops->execute_sync_cache) { + size = 0; + cmd->execute_cmd = sbc_emulate_noop; + break; + } /* * Extract LBA and range to be flushed for emulated SYNCHRONIZE_CACHE -- cgit v1.2.3 From 7ac9ad11b2a5cf77a92b58ee6b672ad2fa155eb1 Mon Sep 17 00:00:00 2001 From: Andy Grover Date: Mon, 4 Mar 2013 13:52:09 -0800 Subject: target/iscsi: Fix mutual CHAP auth on big-endian arches See https://bugzilla.redhat.com/show_bug.cgi?id=916290 Used a temp var since we take its address in sg_init_one. Signed-off-by: Andy Grover Cc: Signed-off-by: Nicholas Bellinger --- drivers/target/iscsi/iscsi_target_auth.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index db0cf7c8adde..a0fc7b9eea65 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c @@ -166,6 +166,7 @@ static int chap_server_compute_md5( { char *endptr; unsigned long id; + unsigned char id_as_uchar; unsigned char digest[MD5_SIGNATURE_SIZE]; unsigned char type, response[MD5_SIGNATURE_SIZE * 2 + 2]; unsigned char identifier[10], *challenge = NULL; @@ -355,7 +356,9 @@ static int chap_server_compute_md5( goto out; } - sg_init_one(&sg, &id, 1); + /* To handle both endiannesses */ + id_as_uchar = id; + sg_init_one(&sg, &id_as_uchar, 1); ret = crypto_hash_update(&desc, &sg, 1); if (ret < 0) { pr_err("crypto_hash_update() failed for id\n"); -- cgit v1.2.3 From 0fb889b83186e54c0cfa79516599f2267fb553fb Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Fri, 15 Mar 2013 17:19:26 +0800 Subject: target: fix possible memory leak in core_tpg_register() 'se_tpg->tpg_lun_list' is malloced in core_tpg_register() and should be freed before leaving from the error handling cases, otherwise it will cause memory leak. 'se_tpg' is malloced out of this function, and will be freed if we return error, so remove free for 'se_tpg'. Signed-off-by: Wei Yongjun Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_tpg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/target_core_tpg.c b/drivers/target/target_core_tpg.c index 9169d6a5d7e4..aac9d2727e3c 100644 --- a/drivers/target/target_core_tpg.c +++ b/drivers/target/target_core_tpg.c @@ -711,7 +711,8 @@ int core_tpg_register( if (se_tpg->se_tpg_type == TRANSPORT_TPG_TYPE_NORMAL) { if (core_tpg_setup_virtual_lun0(se_tpg) < 0) { - kfree(se_tpg); + array_free(se_tpg->tpg_lun_list, + TRANSPORT_MAX_LUNS_PER_TPG); return -ENOMEM; } } -- cgit v1.2.3 From 5a4c060114822255302d4763ad6712f9cde2372b Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Mon, 18 Mar 2013 21:19:49 +0100 Subject: hwmon: (lm75.h) Update header inclusion File lm75.h used to include for SENSORS_LIMIT() but this function is gone by now. Instead we call clamp_val() so we should include , where this function is declared. Signed-off-by: Jean Delvare Reviewed-by: Guenter Roeck --- drivers/hwmon/lm75.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/hwmon/lm75.h b/drivers/hwmon/lm75.h index 668ff4721323..5cde94e56f17 100644 --- a/drivers/hwmon/lm75.h +++ b/drivers/hwmon/lm75.h @@ -25,7 +25,7 @@ which contains this code, we don't worry about the wasted space. */ -#include +#include /* straight from the datasheet */ #define LM75_TEMP_MIN (-55000) -- cgit v1.2.3 From 0e5e098ac22dae38f957e951b70d3cf73beff0f7 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Mon, 11 Mar 2013 09:39:55 +0000 Subject: xen-blkback: fix dispatch_rw_block_io() error path Commit 7708992 ("xen/blkback: Seperate the bio allocation and the bio submission") consolidated the pendcnt updates to just a single write, neglecting the fact that the error path relied on it getting set to 1 up front (such that the decrement in __end_block_io_op() would actually drop the count to zero, triggering the necessary cleanup actions). Also remove a misleading and a stale (after said commit) comment. CC: stable@vger.kernel.org Signed-off-by: Jan Beulich Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index eaccc222a1dc..477a17c20820 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -1001,13 +1001,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, bio->bi_end_io = end_block_io_op; } - /* - * We set it one so that the last submit_bio does not have to call - * atomic_inc. - */ atomic_set(&pending_req->pendcnt, nbio); - - /* Get a reference count for the disk queue and start sending I/O */ blk_start_plug(&plug); for (i = 0; i < nbio; i++) @@ -1035,6 +1029,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, fail_put_bio: for (i = 0; i < nbio; i++) bio_put(biolist[i]); + atomic_set(&pending_req->pendcnt, 1); __end_block_io_op(pending_req, -EINVAL); msleep(1); /* back off a bit */ return -EIO; -- cgit v1.2.3 From 29d0b218c87ace1078e08bb32c2e72fc96fa3db3 Mon Sep 17 00:00:00 2001 From: Mihnea Dobrescu-Balaur Date: Mon, 11 Mar 2013 13:23:36 +0200 Subject: xen-blkfront: replace kmalloc and then memcpy with kmemdup The benefits are: * code is cleaner * kmemdup adds additional debugging info useful for tracking the real place where memory was allocated (CONFIG_DEBUG_SLAB). Signed-off-by: Mihnea Dobrescu-Balaur Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index c3dae2e0f290..962064487ef7 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1203,11 +1203,10 @@ static int blkif_recover(struct blkfront_info *info) int j; /* Stage 1: Make a safe copy of the shadow state. */ - copy = kmalloc(sizeof(info->shadow), + copy = kmemdup(info->shadow, sizeof(info->shadow), GFP_NOIO | __GFP_REPEAT | __GFP_HIGH); if (!copy) return -ENOMEM; - memcpy(copy, info->shadow, sizeof(info->shadow)); /* Stage 2: Set up free list. */ memset(&info->shadow, 0, sizeof(info->shadow)); -- cgit v1.2.3 From 038e0af4a4fc4db9631aef39ab53e5d991b972ef Mon Sep 17 00:00:00 2001 From: Asias He Date: Fri, 15 Mar 2013 09:14:05 +0800 Subject: tcm_vhost: Add missed lock in vhost_scsi_clear_endpoint() tv_tpg->tv_tpg_vhost_count should be protected by tv_tpg->tv_tpg_mutex. Signed-off-by: Asias He Reviewed-by: Stefan Hajnoczi Reviewed-by: Paolo Bonzini Acked-by: Michael S. Tsirkin Signed-off-by: Nicholas Bellinger --- drivers/vhost/tcm_vhost.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 9951297b2427..79d3aeaff8fa 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -850,7 +850,7 @@ static int vhost_scsi_clear_endpoint( for (index = 0; index < vs->dev.nvqs; ++index) { if (!vhost_vq_access_ok(&vs->vqs[index])) { ret = -EFAULT; - goto err; + goto err_dev; } } for (i = 0; i < VHOST_SCSI_MAX_TARGET; i++) { @@ -860,10 +860,11 @@ static int vhost_scsi_clear_endpoint( if (!tv_tpg) continue; + mutex_lock(&tv_tpg->tv_tpg_mutex); tv_tport = tv_tpg->tport; if (!tv_tport) { ret = -ENODEV; - goto err; + goto err_tpg; } if (strcmp(tv_tport->tport_name, t->vhost_wwpn)) { @@ -872,16 +873,19 @@ static int vhost_scsi_clear_endpoint( tv_tport->tport_name, tv_tpg->tport_tpgt, t->vhost_wwpn, t->vhost_tpgt); ret = -EINVAL; - goto err; + goto err_tpg; } tv_tpg->tv_tpg_vhost_count--; vs->vs_tpg[target] = NULL; vs->vs_endpoint = false; + mutex_unlock(&tv_tpg->tv_tpg_mutex); } mutex_unlock(&vs->dev.mutex); return 0; -err: +err_tpg: + mutex_unlock(&tv_tpg->tv_tpg_mutex); +err_dev: mutex_unlock(&vs->dev.mutex); return ret; } -- cgit v1.2.3 From 72c77539fd56f5ba8dd538df9f3ce0e331fe601c Mon Sep 17 00:00:00 2001 From: Asias He Date: Fri, 15 Mar 2013 09:14:06 +0800 Subject: tcm_vhost: Flush vhost_work in vhost_scsi_flush() We also need to flush the vhost_works. It is the completion vhost_work currently. Signed-off-by: Asias He Reviewed-by: Stefan Hajnoczi Reviewed-by: Paolo Bonzini Acked-by: Michael S. Tsirkin Signed-off-by: Nicholas Bellinger --- drivers/vhost/tcm_vhost.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c index 79d3aeaff8fa..43fb11ee2e8d 100644 --- a/drivers/vhost/tcm_vhost.c +++ b/drivers/vhost/tcm_vhost.c @@ -941,6 +941,7 @@ static void vhost_scsi_flush(struct vhost_scsi *vs) for (i = 0; i < VHOST_SCSI_MAX_VQ; i++) vhost_scsi_flush_vq(vs, i); + vhost_work_flush(&vs->dev, &vs->vs_completion_work); } static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) -- cgit v1.2.3 From 27ca0391fb717eecb9b9ca29ad4b9e8d7a84aba5 Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Sat, 9 Mar 2013 22:19:35 +0100 Subject: staging: zcache: fix typo "64_BIT" Signed-off-by: Paul Bolle Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zcache/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/staging/zcache/Kconfig b/drivers/staging/zcache/Kconfig index 73582705e8c5..5c3714530961 100644 --- a/drivers/staging/zcache/Kconfig +++ b/drivers/staging/zcache/Kconfig @@ -15,7 +15,7 @@ config RAMSTER depends on CONFIGFS_FS=y && SYSFS=y && !HIGHMEM && ZCACHE=y depends on NET # must ensure struct page is 8-byte aligned - select HAVE_ALIGNED_STRUCT_PAGE if !64_BIT + select HAVE_ALIGNED_STRUCT_PAGE if !64BIT default n help RAMster allows RAM on other machines in a cluster to be utilized -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From e71918ea66121985f287c0c3d0efa9c4c35da7fa Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Mar 2013 17:56:44 -0300 Subject: [media] ir: IR_RX51 only works on OMAP2 This driver can be enabled on OMAP1 at the moment, which breaks allyesconfig for that platform. Let's mark it OMAP2PLUS-only in Kconfig, since that is the only thing it builds on. Signed-off-by: Arnd Bergmann Acked-by: Timo Kokkonen Acked-by: Tony Lindgren Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 19f3563c61da..5a79c333d45e 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig @@ -291,7 +291,7 @@ config IR_TTUSBIR config IR_RX51 tristate "Nokia N900 IR transmitter diode" - depends on OMAP_DM_TIMER && LIRC && !ARCH_MULTIPLATFORM + depends on OMAP_DM_TIMER && ARCH_OMAP2PLUS && LIRC && !ARCH_MULTIPLATFORM ---help--- Say Y or M here if you want to enable support for the IR transmitter diode built in the Nokia N900 (RX51) device. -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 6a15075eced2d780fa6c5d83682410f47f2e800b Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 18 Mar 2013 19:24:02 +0100 Subject: ARM: video: mxs: Fix mxsfb misconfiguring VDCTRL0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The issue fixed by this patch manifests only then using X11 with mxsfb driver. The X11 will display either shifted image or otherwise distorted image on the LCD. The problem is that the X11 tries to reconfigure the framebuffer and along the way calls fb_ops.fb_set_par() with X11's desired configuration values. The field of particular interest is fb_info->var.sync which contains non-standard values if configured by kernel. These are either FB_SYNC_DATA_ENABLE_HIGH_ACT, FB_SYNC_DOTCLK_FAILING_ACT or both, depending on the platform configuration. Both of these values are defined in the include/linux/mxsfb.h file. The driver interprets these values and configures the LCD controller accordingly. Yet X11 only has access to the standard values for this field defined in include/uapi/linux/fb.h and thus, unlike kernel, omits these special values. This results in distorted image on the LCD. This patch moves these non-standard values into new field of the mxsfb_platform_data structure so the driver can in turn check this field instead of the video mode field for these specific portions. Moreover, this patch prefixes these values with MXSFB_SYNC_ prefix instead of FB_SYNC_ prefix to prevent confusion of subsequent users. Signed-off-by: Marek Vasut Cc: Fabio Estevam Cc: Linux ARM Cc: Linux FBDEV Cc: Lothar Waßmann Cc: Sascha Hauer Tested-by: Fabio Estevam Signed-off-by: Shawn Guo --- arch/arm/mach-mxs/mach-mxs.c | 24 ++++++++++++------------ drivers/video/mxsfb.c | 7 +++++-- include/linux/mxsfb.h | 7 +++++-- 3 files changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index 3218f1f2c0e0..e7b781d3788f 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -41,8 +41,6 @@ static struct fb_videomode mx23evk_video_modes[] = { .lower_margin = 4, .hsync_len = 1, .vsync_len = 1, - .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT | - FB_SYNC_DOTCLK_FAILING_ACT, }, }; @@ -59,8 +57,6 @@ static struct fb_videomode mx28evk_video_modes[] = { .lower_margin = 10, .hsync_len = 10, .vsync_len = 10, - .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT | - FB_SYNC_DOTCLK_FAILING_ACT, }, }; @@ -77,7 +73,6 @@ static struct fb_videomode m28evk_video_modes[] = { .lower_margin = 45, .hsync_len = 1, .vsync_len = 1, - .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT, }, }; @@ -94,9 +89,7 @@ static struct fb_videomode apx4devkit_video_modes[] = { .lower_margin = 13, .hsync_len = 48, .vsync_len = 3, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | - FB_SYNC_DATA_ENABLE_HIGH_ACT | - FB_SYNC_DOTCLK_FAILING_ACT, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, }, }; @@ -113,9 +106,7 @@ static struct fb_videomode apf28dev_video_modes[] = { .lower_margin = 0x15, .hsync_len = 64, .vsync_len = 4, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT | - FB_SYNC_DATA_ENABLE_HIGH_ACT | - FB_SYNC_DOTCLK_FAILING_ACT, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, }, }; @@ -132,7 +123,6 @@ static struct fb_videomode cfa10049_video_modes[] = { .lower_margin = 2, .hsync_len = 15, .vsync_len = 15, - .sync = FB_SYNC_DATA_ENABLE_HIGH_ACT }, }; @@ -259,6 +249,8 @@ static void __init imx23_evk_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(mx23evk_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; + mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | + MXSFB_SYNC_DOTCLK_FAILING_ACT; } static inline void enable_clk_enet_out(void) @@ -278,6 +270,8 @@ static void __init imx28_evk_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(mx28evk_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; + mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | + MXSFB_SYNC_DOTCLK_FAILING_ACT; mxs_saif_clkmux_select(MXS_DIGCTL_SAIF_CLKMUX_EXTMSTR0); } @@ -297,6 +291,7 @@ static void __init m28evk_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(m28evk_video_modes); mxsfb_pdata.default_bpp = 16; mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; + mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; } static void __init sc_sps1_init(void) @@ -322,6 +317,8 @@ static void __init apx4devkit_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(apx4devkit_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_24BIT; + mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | + MXSFB_SYNC_DOTCLK_FAILING_ACT; } #define ENET0_MDC__GPIO_4_0 MXS_GPIO_NR(4, 0) @@ -407,6 +404,7 @@ static void __init cfa10049_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(cfa10049_video_modes); mxsfb_pdata.default_bpp = 32; mxsfb_pdata.ld_intf_width = STMLCDIF_18BIT; + mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT; } static void __init cfa10037_init(void) @@ -423,6 +421,8 @@ static void __init apf28_init(void) mxsfb_pdata.mode_count = ARRAY_SIZE(apf28dev_video_modes); mxsfb_pdata.default_bpp = 16; mxsfb_pdata.ld_intf_width = STMLCDIF_16BIT; + mxsfb_pdata.sync = MXSFB_SYNC_DATA_ENABLE_HIGH_ACT | + MXSFB_SYNC_DOTCLK_FAILING_ACT; } static void __init mxs_machine_init(void) diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c index 755556ca5b2d..45169cbaba6e 100644 --- a/drivers/video/mxsfb.c +++ b/drivers/video/mxsfb.c @@ -169,6 +169,7 @@ struct mxsfb_info { unsigned dotclk_delay; const struct mxsfb_devdata *devdata; int mapped; + u32 sync; }; #define mxsfb_is_v3(host) (host->devdata->ipversion == 3) @@ -456,9 +457,9 @@ static int mxsfb_set_par(struct fb_info *fb_info) vdctrl0 |= VDCTRL0_HSYNC_ACT_HIGH; if (fb_info->var.sync & FB_SYNC_VERT_HIGH_ACT) vdctrl0 |= VDCTRL0_VSYNC_ACT_HIGH; - if (fb_info->var.sync & FB_SYNC_DATA_ENABLE_HIGH_ACT) + if (host->sync & MXSFB_SYNC_DATA_ENABLE_HIGH_ACT) vdctrl0 |= VDCTRL0_ENABLE_ACT_HIGH; - if (fb_info->var.sync & FB_SYNC_DOTCLK_FAILING_ACT) + if (host->sync & MXSFB_SYNC_DOTCLK_FAILING_ACT) vdctrl0 |= VDCTRL0_DOTCLK_ACT_FAILING; writel(vdctrl0, host->base + LCDC_VDCTRL0); @@ -861,6 +862,8 @@ static int mxsfb_probe(struct platform_device *pdev) INIT_LIST_HEAD(&fb_info->modelist); + host->sync = pdata->sync; + ret = mxsfb_init_fbinfo(host); if (ret != 0) goto error_init_fb; diff --git a/include/linux/mxsfb.h b/include/linux/mxsfb.h index f14943d55315..f80af8674342 100644 --- a/include/linux/mxsfb.h +++ b/include/linux/mxsfb.h @@ -24,8 +24,8 @@ #define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */ #define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */ -#define FB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6) -#define FB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */ +#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6) +#define MXSFB_SYNC_DOTCLK_FAILING_ACT (1 << 7) /* failing/negtive edge sampling */ struct mxsfb_platform_data { struct fb_videomode *mode_list; @@ -44,6 +44,9 @@ struct mxsfb_platform_data { * allocated. If specified,fb_size must also be specified. * fb_phys must be unused by Linux. */ + u32 sync; /* sync mask, contains MXSFB specifics not + * carried in fb_info->var.sync + */ }; #endif /* __LINUX_MXSFB_H */ -- cgit v1.2.3 From 4fa133954e91b83cfa22947579154c6f16e1b2b4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Mar 2013 09:57:57 +1000 Subject: drm/nouveau/core: fix return value of nouveau_object_del() Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/core/object.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/core/core/object.c b/drivers/gpu/drm/nouveau/core/core/object.c index 0daab62ea14c..3b2e7b6304d3 100644 --- a/drivers/gpu/drm/nouveau/core/core/object.c +++ b/drivers/gpu/drm/nouveau/core/core/object.c @@ -278,7 +278,6 @@ nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle) struct nouveau_object *parent = NULL; struct nouveau_object *namedb = NULL; struct nouveau_handle *handle = NULL; - int ret = -EINVAL; parent = nouveau_handle_ref(client, _parent); if (!parent) @@ -295,7 +294,7 @@ nouveau_object_del(struct nouveau_object *client, u32 _parent, u32 _handle) } nouveau_object_ref(NULL, &parent); - return ret; + return handle ? 0 : -EINVAL; } int -- cgit v1.2.3 From f60b6e7a6078ceae438a95b808be04cd98f9909a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Mar 2013 15:20:00 +1000 Subject: drm/nv50/kms: prevent lockdep false-positive in page flipping path Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 2db57990f65c..7f0e6c3f37d1 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -524,6 +524,8 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, swap_interval <<= 4; if (swap_interval == 0) swap_interval |= 0x100; + if (chan == NULL) + evo_sync(crtc->dev); push = evo_wait(sync, 128); if (unlikely(push == NULL)) @@ -586,8 +588,6 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, sync->addr ^= 0x10; sync->data++; FIRE_RING (chan); - } else { - evo_sync(crtc->dev); } /* queue the flip */ -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 From 217fd5e709f029c125a9d39de5f13387407f131a Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Mon, 18 Mar 2013 17:49:33 +0100 Subject: xen-blkback: fix foreach_grant_safe to handle empty lists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We may use foreach_grant_safe in the future with empty lists, so make sure we can handle them. Signed-off-by: Roger Pau Monné Cc: xen-devel@lists.xen.org Cc: Konrad Rzeszutek Wilk Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 477a17c20820..2cf8381a1c6e 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -164,7 +164,7 @@ static void make_response(struct xen_blkif *blkif, u64 id, #define foreach_grant_safe(pos, n, rbtree, node) \ for ((pos) = container_of(rb_first((rbtree)), typeof(*(pos)), node), \ - (n) = rb_next(&(pos)->node); \ + (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL; \ &(pos)->node != NULL; \ (pos) = container_of(n, typeof(*(pos)), node), \ (n) = (&(pos)->node != NULL) ? rb_next(&(pos)->node) : NULL) -- cgit v1.2.3 From 82f77cf9704cd06c452019421e5aada3a0648c76 Mon Sep 17 00:00:00 2001 From: Stefan Raspl Date: Mon, 18 Mar 2013 20:04:42 +0000 Subject: qeth: delay feature trace Delay tracing of the card features until the optional commands have been enabled. Signed-off-by: Stefan Raspl Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 091ca0efa1c5..4eb7ea3fc1c3 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -3348,7 +3348,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode) rc = -ENODEV; goto out_remove; } - qeth_trace_features(card); if (!card->dev && qeth_l3_setup_netdev(card)) { rc = -ENODEV; @@ -3425,6 +3424,7 @@ contin: qeth_l3_set_multicast_list(card->dev); rtnl_unlock(); } + qeth_trace_features(card); /* let user_space know that device is online */ kobject_uevent(&gdev->dev.kobj, KOBJ_CHANGE); mutex_unlock(&card->conf_mutex); -- cgit v1.2.3 From 82e2e782a3e486e3bfcc6130f0ebc28453af9955 Mon Sep 17 00:00:00 2001 From: Stefan Raspl Date: Mon, 18 Mar 2013 20:04:43 +0000 Subject: qeth: Fix invalid router settings handling Give a bad return code when specifying a router setting that is either invalid or not support on the respective device type. In addition, fall back the previous setting instead of silently switching back to 'no routing'. Signed-off-by: Stefan Raspl Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_l3_main.c | 17 +++++++++++------ drivers/s390/net/qeth_l3_sys.c | 2 ++ 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index 4eb7ea3fc1c3..b6da6cec9c3e 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -623,7 +623,7 @@ static int qeth_l3_send_setrouting(struct qeth_card *card, return rc; } -static void qeth_l3_correct_routing_type(struct qeth_card *card, +static int qeth_l3_correct_routing_type(struct qeth_card *card, enum qeth_routing_types *type, enum qeth_prot_versions prot) { if (card->info.type == QETH_CARD_TYPE_IQD) { @@ -632,7 +632,7 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card, case PRIMARY_CONNECTOR: case SECONDARY_CONNECTOR: case MULTICAST_ROUTER: - return; + return 0; default: goto out_inval; } @@ -641,17 +641,18 @@ static void qeth_l3_correct_routing_type(struct qeth_card *card, case NO_ROUTER: case PRIMARY_ROUTER: case SECONDARY_ROUTER: - return; + return 0; case MULTICAST_ROUTER: if (qeth_is_ipafunc_supported(card, prot, IPA_OSA_MC_ROUTER)) - return; + return 0; default: goto out_inval; } } out_inval: *type = NO_ROUTER; + return -EINVAL; } int qeth_l3_setrouting_v4(struct qeth_card *card) @@ -660,8 +661,10 @@ int qeth_l3_setrouting_v4(struct qeth_card *card) QETH_CARD_TEXT(card, 3, "setrtg4"); - qeth_l3_correct_routing_type(card, &card->options.route4.type, + rc = qeth_l3_correct_routing_type(card, &card->options.route4.type, QETH_PROT_IPV4); + if (rc) + return rc; rc = qeth_l3_send_setrouting(card, card->options.route4.type, QETH_PROT_IPV4); @@ -683,8 +686,10 @@ int qeth_l3_setrouting_v6(struct qeth_card *card) if (!qeth_is_supported(card, IPA_IPV6)) return 0; - qeth_l3_correct_routing_type(card, &card->options.route6.type, + rc = qeth_l3_correct_routing_type(card, &card->options.route6.type, QETH_PROT_IPV6); + if (rc) + return rc; rc = qeth_l3_send_setrouting(card, card->options.route6.type, QETH_PROT_IPV6); diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c index ebc379486267..e70af2406ff9 100644 --- a/drivers/s390/net/qeth_l3_sys.c +++ b/drivers/s390/net/qeth_l3_sys.c @@ -87,6 +87,8 @@ static ssize_t qeth_l3_dev_route_store(struct qeth_card *card, rc = qeth_l3_setrouting_v6(card); } out: + if (rc) + route->type = old_route_type; mutex_unlock(&card->conf_mutex); return rc ? rc : count; } -- cgit v1.2.3 From 271648b4c610eed540daaf9ff366209825757565 Mon Sep 17 00:00:00 2001 From: Frank Blaschka Date: Mon, 18 Mar 2013 20:04:44 +0000 Subject: qeth: Fix scatter-gather regression This patch fixes a scatter-gather regression introduced with commit 5640f768 net: use a per task frag allocator Now the qeth driver can cope with bigger framents and split a fragment in sub framents if required. Signed-off-by: Frank Blaschka Signed-off-by: David S. Miller --- drivers/s390/net/qeth_core.h | 1 + drivers/s390/net/qeth_core_main.c | 45 +++++++++++++++++++++++++++++++++------ drivers/s390/net/qeth_l3_main.c | 4 +++- 3 files changed, 42 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h index d87961d4c0de..8c0622399fcd 100644 --- a/drivers/s390/net/qeth_core.h +++ b/drivers/s390/net/qeth_core.h @@ -916,6 +916,7 @@ int qeth_send_control_data(struct qeth_card *, int, struct qeth_cmd_buffer *, void *reply_param); int qeth_get_priority_queue(struct qeth_card *, struct sk_buff *, int, int); int qeth_get_elements_no(struct qeth_card *, void *, struct sk_buff *, int); +int qeth_get_elements_for_frags(struct sk_buff *); int qeth_do_send_packet_fast(struct qeth_card *, struct qeth_qdio_out_q *, struct sk_buff *, struct qeth_hdr *, int, int, int); int qeth_do_send_packet(struct qeth_card *, struct qeth_qdio_out_q *, diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c index 0d8cdff81813..0d73a999983d 100644 --- a/drivers/s390/net/qeth_core_main.c +++ b/drivers/s390/net/qeth_core_main.c @@ -3679,6 +3679,25 @@ int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb, } EXPORT_SYMBOL_GPL(qeth_get_priority_queue); +int qeth_get_elements_for_frags(struct sk_buff *skb) +{ + int cnt, length, e, elements = 0; + struct skb_frag_struct *frag; + char *data; + + for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) { + frag = &skb_shinfo(skb)->frags[cnt]; + data = (char *)page_to_phys(skb_frag_page(frag)) + + frag->page_offset; + length = frag->size; + e = PFN_UP((unsigned long)data + length - 1) - + PFN_DOWN((unsigned long)data); + elements += e; + } + return elements; +} +EXPORT_SYMBOL_GPL(qeth_get_elements_for_frags); + int qeth_get_elements_no(struct qeth_card *card, void *hdr, struct sk_buff *skb, int elems) { @@ -3686,7 +3705,8 @@ int qeth_get_elements_no(struct qeth_card *card, void *hdr, int elements_needed = PFN_UP((unsigned long)skb->data + dlen - 1) - PFN_DOWN((unsigned long)skb->data); - elements_needed += skb_shinfo(skb)->nr_frags; + elements_needed += qeth_get_elements_for_frags(skb); + if ((elements_needed + elems) > QETH_MAX_BUFFER_ELEMENTS(card)) { QETH_DBF_MESSAGE(2, "Invalid size of IP packet " "(Number=%d / Length=%d). Discarded.\n", @@ -3771,12 +3791,23 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb, for (cnt = 0; cnt < skb_shinfo(skb)->nr_frags; cnt++) { frag = &skb_shinfo(skb)->frags[cnt]; - buffer->element[element].addr = (char *) - page_to_phys(skb_frag_page(frag)) - + frag->page_offset; - buffer->element[element].length = frag->size; - buffer->element[element].eflags = SBAL_EFLAGS_MIDDLE_FRAG; - element++; + data = (char *)page_to_phys(skb_frag_page(frag)) + + frag->page_offset; + length = frag->size; + while (length > 0) { + length_here = PAGE_SIZE - + ((unsigned long) data % PAGE_SIZE); + if (length < length_here) + length_here = length; + + buffer->element[element].addr = data; + buffer->element[element].length = length_here; + buffer->element[element].eflags = + SBAL_EFLAGS_MIDDLE_FRAG; + length -= length_here; + data += length_here; + element++; + } } if (buffer->element[element - 1].eflags) diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c index b6da6cec9c3e..8710337dab3e 100644 --- a/drivers/s390/net/qeth_l3_main.c +++ b/drivers/s390/net/qeth_l3_main.c @@ -2903,7 +2903,9 @@ static inline int qeth_l3_tso_elements(struct sk_buff *skb) tcp_hdr(skb)->doff * 4; int tcpd_len = skb->len - (tcpd - (unsigned long)skb->data); int elements = PFN_UP(tcpd + tcpd_len - 1) - PFN_DOWN(tcpd); - elements += skb_shinfo(skb)->nr_frags; + + elements += qeth_get_elements_for_frags(skb); + return elements; } -- cgit v1.2.3 From 155b7edb51430a280f86c1e21b7be308b0d219d4 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Mon, 18 Mar 2013 17:49:34 +0100 Subject: xen-blkfront: switch from llist to list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The git commit f84adf4921ae3115502f44ff467b04bf2f88cf04 (xen-blkfront: drop the use of llist_for_each_entry_safe) was a stop-gate to fix a GCC4.1 bug. The appropiate way is to actually use an list instead of using an llist. As such this patch replaces the usage of llist with an list. Since we always manipulate the list while holding the io_lock, there's no need for additional locking (llist used previously is safe to use concurrently without additional locking). Signed-off-by: Roger Pau Monné CC: stable@vger.kernel.org [v1: Redid the git commit description] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 41 ++++++++++++++++++----------------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 962064487ef7..97324cd18f4b 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include @@ -68,7 +68,7 @@ enum blkif_state { struct grant { grant_ref_t gref; unsigned long pfn; - struct llist_node node; + struct list_head node; }; struct blk_shadow { @@ -105,7 +105,7 @@ struct blkfront_info struct work_struct work; struct gnttab_free_callback callback; struct blk_shadow shadow[BLK_RING_SIZE]; - struct llist_head persistent_gnts; + struct list_head persistent_gnts; unsigned int persistent_gnts_c; unsigned long shadow_free; unsigned int feature_flush; @@ -371,10 +371,11 @@ static int blkif_queue_request(struct request *req) lsect = fsect + (sg->length >> 9) - 1; if (info->persistent_gnts_c) { - BUG_ON(llist_empty(&info->persistent_gnts)); - gnt_list_entry = llist_entry( - llist_del_first(&info->persistent_gnts), - struct grant, node); + BUG_ON(list_empty(&info->persistent_gnts)); + gnt_list_entry = list_first_entry( + &info->persistent_gnts, + struct grant, node); + list_del(&gnt_list_entry->node); ref = gnt_list_entry->gref; buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); @@ -790,9 +791,8 @@ static void blkif_restart_queue(struct work_struct *work) static void blkif_free(struct blkfront_info *info, int suspend) { - struct llist_node *all_gnts; - struct grant *persistent_gnt, *tmp; - struct llist_node *n; + struct grant *persistent_gnt; + struct grant *n; /* Prevent new requests being issued until we fix things up. */ spin_lock_irq(&info->io_lock); @@ -804,20 +804,15 @@ static void blkif_free(struct blkfront_info *info, int suspend) /* Remove all persistent grants */ if (info->persistent_gnts_c) { - all_gnts = llist_del_all(&info->persistent_gnts); - persistent_gnt = llist_entry(all_gnts, typeof(*(persistent_gnt)), node); - while (persistent_gnt) { + list_for_each_entry_safe(persistent_gnt, n, + &info->persistent_gnts, node) { + list_del(&persistent_gnt->node); gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); __free_page(pfn_to_page(persistent_gnt->pfn)); - tmp = persistent_gnt; - n = persistent_gnt->node.next; - if (n) - persistent_gnt = llist_entry(n, typeof(*(persistent_gnt)), node); - else - persistent_gnt = NULL; - kfree(tmp); + kfree(persistent_gnt); + info->persistent_gnts_c--; } - info->persistent_gnts_c = 0; + BUG_ON(info->persistent_gnts_c != 0); } /* No more gnttab callback work. */ @@ -875,7 +870,7 @@ static void blkif_completion(struct blk_shadow *s, struct blkfront_info *info, } /* Add the persistent grant into the list of free grants */ for (i = 0; i < s->req.u.rw.nr_segments; i++) { - llist_add(&s->grants_used[i]->node, &info->persistent_gnts); + list_add(&s->grants_used[i]->node, &info->persistent_gnts); info->persistent_gnts_c++; } } @@ -1171,7 +1166,7 @@ static int blkfront_probe(struct xenbus_device *dev, spin_lock_init(&info->io_lock); info->xbdev = dev; info->vdevice = vdevice; - init_llist_head(&info->persistent_gnts); + INIT_LIST_HEAD(&info->persistent_gnts); info->persistent_gnts_c = 0; info->connected = BLKIF_STATE_DISCONNECTED; INIT_WORK(&info->work, blkif_restart_queue); -- cgit v1.2.3 From ffb1dabd1eb10c76a1e7af62f75a1aaa8d590b5a Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Mon, 18 Mar 2013 17:49:32 +0100 Subject: xen-blkback: don't store dev_bus_addr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dev_bus_addr returned in the grant ref map operation is the mfn of the passed page, there's no need to store it in the persistent grant entry, since we can always get it provided that we have the page. This reduces the memory overhead of persistent grants in blkback. While at it, rename the 'seg[i].buf' to be 'seg[i].offset' as it makes much more sense - as we use that value in bio_add_page which as the fourth argument expects the offset. We hadn't used the physical address as part of this at all. Signed-off-by: Roger Pau Monné Cc: Konrad Rzeszutek Wilk Cc: xen-devel@lists.xen.org [v1: s/buf/offset/] Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkback/blkback.c | 21 ++++++--------------- drivers/block/xen-blkback/common.h | 1 - 2 files changed, 6 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkback/blkback.c b/drivers/block/xen-blkback/blkback.c index 2cf8381a1c6e..dd5b2fed97e9 100644 --- a/drivers/block/xen-blkback/blkback.c +++ b/drivers/block/xen-blkback/blkback.c @@ -442,7 +442,7 @@ int xen_blkif_schedule(void *arg) } struct seg_buf { - unsigned long buf; + unsigned int offset; unsigned int nsec; }; /* @@ -621,30 +621,21 @@ static int xen_blkbk_map(struct blkif_request *req, * If this is a new persistent grant * save the handler */ - persistent_gnts[i]->handle = map[j].handle; - persistent_gnts[i]->dev_bus_addr = - map[j++].dev_bus_addr; + persistent_gnts[i]->handle = map[j++].handle; } pending_handle(pending_req, i) = persistent_gnts[i]->handle; if (ret) continue; - - seg[i].buf = persistent_gnts[i]->dev_bus_addr | - (req->u.rw.seg[i].first_sect << 9); } else { - pending_handle(pending_req, i) = map[j].handle; + pending_handle(pending_req, i) = map[j++].handle; bitmap_set(pending_req->unmap_seg, i, 1); - if (ret) { - j++; + if (ret) continue; - } - - seg[i].buf = map[j++].dev_bus_addr | - (req->u.rw.seg[i].first_sect << 9); } + seg[i].offset = (req->u.rw.seg[i].first_sect << 9); } return ret; } @@ -971,7 +962,7 @@ static int dispatch_rw_block_io(struct xen_blkif *blkif, (bio_add_page(bio, pages[i], seg[i].nsec << 9, - seg[i].buf & ~PAGE_MASK) == 0)) { + seg[i].offset) == 0)) { bio = bio_alloc(GFP_KERNEL, nseg-i); if (unlikely(bio == NULL)) diff --git a/drivers/block/xen-blkback/common.h b/drivers/block/xen-blkback/common.h index da78346487ae..60103e2517ba 100644 --- a/drivers/block/xen-blkback/common.h +++ b/drivers/block/xen-blkback/common.h @@ -187,7 +187,6 @@ struct persistent_gnt { struct page *page; grant_ref_t gnt; grant_handle_t handle; - uint64_t dev_bus_addr; struct rb_node node; }; -- cgit v1.2.3 From 9c1e050caeb4d1250f8ceef1180a8b3d0db6c624 Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Mon, 18 Mar 2013 17:49:35 +0100 Subject: xen-blkfront: pre-allocate pages for requests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This prevents us from having to call alloc_page while we are preparing the request. Since blkfront was calling alloc_page with a spinlock held we used GFP_ATOMIC, which can fail if we are requesting a lot of pages since it is using the emergency memory pools. Allocating all the pages at init prevents us from having to call alloc_page, thus preventing possible failures. Signed-off-by: Roger Pau Monné Cc: Konrad Rzeszutek Wilk Cc: xen-devel@lists.xen.org Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 120 ++++++++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 41 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 97324cd18f4b..c64043323399 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -165,6 +165,69 @@ static int add_id_to_freelist(struct blkfront_info *info, return 0; } +static int fill_grant_buffer(struct blkfront_info *info, int num) +{ + struct page *granted_page; + struct grant *gnt_list_entry, *n; + int i = 0; + + while(i < num) { + gnt_list_entry = kzalloc(sizeof(struct grant), GFP_NOIO); + if (!gnt_list_entry) + goto out_of_memory; + + granted_page = alloc_page(GFP_NOIO); + if (!granted_page) { + kfree(gnt_list_entry); + goto out_of_memory; + } + + gnt_list_entry->pfn = page_to_pfn(granted_page); + gnt_list_entry->gref = GRANT_INVALID_REF; + list_add(&gnt_list_entry->node, &info->persistent_gnts); + i++; + } + + return 0; + +out_of_memory: + list_for_each_entry_safe(gnt_list_entry, n, + &info->persistent_gnts, node) { + list_del(&gnt_list_entry->node); + __free_page(pfn_to_page(gnt_list_entry->pfn)); + kfree(gnt_list_entry); + i--; + } + BUG_ON(i != 0); + return -ENOMEM; +} + +static struct grant *get_grant(grant_ref_t *gref_head, + struct blkfront_info *info) +{ + struct grant *gnt_list_entry; + unsigned long buffer_mfn; + + BUG_ON(list_empty(&info->persistent_gnts)); + gnt_list_entry = list_first_entry(&info->persistent_gnts, struct grant, + node); + list_del(&gnt_list_entry->node); + + if (gnt_list_entry->gref != GRANT_INVALID_REF) { + info->persistent_gnts_c--; + return gnt_list_entry; + } + + /* Assign a gref to this page */ + gnt_list_entry->gref = gnttab_claim_grant_reference(gref_head); + BUG_ON(gnt_list_entry->gref == -ENOSPC); + buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); + gnttab_grant_foreign_access_ref(gnt_list_entry->gref, + info->xbdev->otherend_id, + buffer_mfn, 0); + return gnt_list_entry; +} + static const char *op_name(int op) { static const char *const names[] = { @@ -306,7 +369,6 @@ static int blkif_queue_request(struct request *req) */ bool new_persistent_gnts; grant_ref_t gref_head; - struct page *granted_page; struct grant *gnt_list_entry = NULL; struct scatterlist *sg; @@ -370,42 +432,9 @@ static int blkif_queue_request(struct request *req) fsect = sg->offset >> 9; lsect = fsect + (sg->length >> 9) - 1; - if (info->persistent_gnts_c) { - BUG_ON(list_empty(&info->persistent_gnts)); - gnt_list_entry = list_first_entry( - &info->persistent_gnts, - struct grant, node); - list_del(&gnt_list_entry->node); - - ref = gnt_list_entry->gref; - buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); - info->persistent_gnts_c--; - } else { - ref = gnttab_claim_grant_reference(&gref_head); - BUG_ON(ref == -ENOSPC); - - gnt_list_entry = - kmalloc(sizeof(struct grant), - GFP_ATOMIC); - if (!gnt_list_entry) - return -ENOMEM; - - granted_page = alloc_page(GFP_ATOMIC); - if (!granted_page) { - kfree(gnt_list_entry); - return -ENOMEM; - } - - gnt_list_entry->pfn = - page_to_pfn(granted_page); - gnt_list_entry->gref = ref; - - buffer_mfn = pfn_to_mfn(page_to_pfn( - granted_page)); - gnttab_grant_foreign_access_ref(ref, - info->xbdev->otherend_id, - buffer_mfn, 0); - } + gnt_list_entry = get_grant(&gref_head, info); + ref = gnt_list_entry->gref; + buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); info->shadow[id].grants_used[i] = gnt_list_entry; @@ -803,17 +832,20 @@ static void blkif_free(struct blkfront_info *info, int suspend) blk_stop_queue(info->rq); /* Remove all persistent grants */ - if (info->persistent_gnts_c) { + if (!list_empty(&info->persistent_gnts)) { list_for_each_entry_safe(persistent_gnt, n, &info->persistent_gnts, node) { list_del(&persistent_gnt->node); - gnttab_end_foreign_access(persistent_gnt->gref, 0, 0UL); + if (persistent_gnt->gref != GRANT_INVALID_REF) { + gnttab_end_foreign_access(persistent_gnt->gref, + 0, 0UL); + info->persistent_gnts_c--; + } __free_page(pfn_to_page(persistent_gnt->pfn)); kfree(persistent_gnt); - info->persistent_gnts_c--; } - BUG_ON(info->persistent_gnts_c != 0); } + BUG_ON(info->persistent_gnts_c != 0); /* No more gnttab callback work. */ gnttab_cancel_free_callback(&info->callback); @@ -1008,6 +1040,12 @@ static int setup_blkring(struct xenbus_device *dev, sg_init_table(info->sg, BLKIF_MAX_SEGMENTS_PER_REQUEST); + /* Allocate memory for grants */ + err = fill_grant_buffer(info, BLK_RING_SIZE * + BLKIF_MAX_SEGMENTS_PER_REQUEST); + if (err) + goto fail; + err = xenbus_grant_ring(dev, virt_to_mfn(info->ring.sring)); if (err < 0) { free_page((unsigned long)sring); -- cgit v1.2.3 From b1173e316bf2ff3c11f46247417f0f5789a4ea0c Mon Sep 17 00:00:00 2001 From: Roger Pau Monne Date: Mon, 18 Mar 2013 17:49:36 +0100 Subject: xen-blkfront: remove frame list from blk_shadow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We already have the frame (pfn of the grant page) stored inside struct grant, so there's no need to keep an aditional list of mapped frames for a specific request. This reduces memory usage in blkfront. Signed-off-by: Roger Pau Monné Cc: Konrad Rzeszutek Wilk Cc: xen-devel@lists.xen.org Signed-off-by: Konrad Rzeszutek Wilk --- drivers/block/xen-blkfront.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index c64043323399..a894f88762d8 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -74,7 +74,6 @@ struct grant { struct blk_shadow { struct blkif_request req; struct request *request; - unsigned long frame[BLKIF_MAX_SEGMENTS_PER_REQUEST]; struct grant *grants_used[BLKIF_MAX_SEGMENTS_PER_REQUEST]; }; @@ -356,7 +355,6 @@ static int blkif_ioctl(struct block_device *bdev, fmode_t mode, static int blkif_queue_request(struct request *req) { struct blkfront_info *info = req->rq_disk->private_data; - unsigned long buffer_mfn; struct blkif_request *ring_req; unsigned long id; unsigned int fsect, lsect; @@ -434,7 +432,6 @@ static int blkif_queue_request(struct request *req) gnt_list_entry = get_grant(&gref_head, info); ref = gnt_list_entry->gref; - buffer_mfn = pfn_to_mfn(gnt_list_entry->pfn); info->shadow[id].grants_used[i] = gnt_list_entry; @@ -465,7 +462,6 @@ static int blkif_queue_request(struct request *req) kunmap_atomic(shared_data); } - info->shadow[id].frame[i] = mfn_to_pfn(buffer_mfn); ring_req->u.rw.seg[i] = (struct blkif_request_segment) { .gref = ref, @@ -1268,7 +1264,7 @@ static int blkif_recover(struct blkfront_info *info) gnttab_grant_foreign_access_ref( req->u.rw.seg[j].gref, info->xbdev->otherend_id, - pfn_to_mfn(info->shadow[req->u.rw.id].frame[j]), + pfn_to_mfn(copy[i].grants_used[j]->pfn), 0); } info->shadow[req->u.rw.id].req = *req; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 547b524636249fbe906ab78a50ab0017c490316c Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Tue, 19 Mar 2013 17:26:57 -0400 Subject: PCI: Use ROM images from firmware only if no other ROM source available MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mantas MikulÄ—nas reported that his graphics hardware failed to initialise after commit f9a37be0f02a ("x86: Use PCI setup data"). The aim of this commit was to ensure that ROM images were available on some Apple systems that don't expose the GPU ROM via any other source. In this case, UEFI appears to have provided a broken ROM image that we were using even though there was a perfectly valid ROM available via other sources. The simplest way to handle this seems to be to just re-order pci_map_rom() and leave any firmare-supplied ROM to last. Signed-off-by: Matthew Garrett Tested-by: Mantas MikulÄ—nas Signed-off-by: Linus Torvalds --- drivers/pci/rom.c | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/rom.c b/drivers/pci/rom.c index ab886b7ee327..b41ac7756a4b 100644 --- a/drivers/pci/rom.c +++ b/drivers/pci/rom.c @@ -100,6 +100,27 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) return min((size_t)(image - rom), size); } +static loff_t pci_find_rom(struct pci_dev *pdev, size_t *size) +{ + struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; + loff_t start; + + /* assign the ROM an address if it doesn't have one */ + if (res->parent == NULL && pci_assign_resource(pdev, PCI_ROM_RESOURCE)) + return 0; + start = pci_resource_start(pdev, PCI_ROM_RESOURCE); + *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); + + if (*size == 0) + return 0; + + /* Enable ROM space decodes */ + if (pci_enable_rom(pdev)) + return 0; + + return start; +} + /** * pci_map_rom - map a PCI ROM to kernel space * @pdev: pointer to pci device struct @@ -114,21 +135,15 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size) void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) { struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; - loff_t start; + loff_t start = 0; void __iomem *rom; - /* - * Some devices may provide ROMs via a source other than the BAR - */ - if (pdev->rom && pdev->romlen) { - *size = pdev->romlen; - return phys_to_virt(pdev->rom); /* * IORESOURCE_ROM_SHADOW set on x86, x86_64 and IA64 supports legacy * memory map if the VGA enable bit of the Bridge Control register is * set for embedded VGA. */ - } else if (res->flags & IORESOURCE_ROM_SHADOW) { + if (res->flags & IORESOURCE_ROM_SHADOW) { /* primary video rom always starts here */ start = (loff_t)0xC0000; *size = 0x20000; /* cover C000:0 through E000:0 */ @@ -139,21 +154,21 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) return (void __iomem *)(unsigned long) pci_resource_start(pdev, PCI_ROM_RESOURCE); } else { - /* assign the ROM an address if it doesn't have one */ - if (res->parent == NULL && - pci_assign_resource(pdev,PCI_ROM_RESOURCE)) - return NULL; - start = pci_resource_start(pdev, PCI_ROM_RESOURCE); - *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - if (*size == 0) - return NULL; - - /* Enable ROM space decodes */ - if (pci_enable_rom(pdev)) - return NULL; + start = pci_find_rom(pdev, size); } } + /* + * Some devices may provide ROMs via a source other than the BAR + */ + if (!start && pdev->rom && pdev->romlen) { + *size = pdev->romlen; + return phys_to_virt(pdev->rom); + } + + if (!start) + return NULL; + rom = ioremap(start, *size); if (!rom) { /* restore enable if ioremap fails */ -- cgit v1.2.3 From c12aba5aa0e60b7947bc8b6ea25ef55c4acf81a4 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 19 Mar 2013 09:56:57 +0100 Subject: drm/i915: stop using GMBUS IRQs on Gen4 chips Commit 28c70f162 ("drm/i915: use the gmbus irq for waits") switched to using GMBUS irqs instead of GPIO bit-banging for chipset generations 4 and above. It turns out though that on many systems this leads to spurious interrupts being generated, long after the register write to disable the IRQs has been issued. Typically this results in the spurious interrupt source getting disabled: [ 9.636345] irq 16: nobody cared (try booting with the "irqpoll" option) [ 9.637915] Pid: 4157, comm: ifup Tainted: GF 3.9.0-rc2-00341-g0863702 #422 [ 9.639484] Call Trace: [ 9.640731] [] __report_bad_irq+0x1d/0xc7 [ 9.640731] [] note_interrupt+0x15b/0x1e8 [ 9.640731] [] handle_irq_event_percpu+0x1bf/0x214 [ 9.640731] [] handle_irq_event+0x3c/0x5c [ 9.640731] [] handle_fasteoi_irq+0x7a/0xb0 [ 9.640731] [] handle_irq+0x1a/0x24 [ 9.640731] [] do_IRQ+0x48/0xaf [ 9.640731] [] common_interrupt+0x6a/0x6a [ 9.640731] [] ? system_call_fastpath+0x16/0x1b [ 9.640731] handlers: [ 9.640731] [] usb_hcd_irq [usbcore] [ 9.640731] [] yenta_interrupt [yenta_socket] [ 9.640731] Disabling IRQ #16 The really curious thing is now that irq 16 is _not_ the interrupt for the i915 driver when using MSI, but it _is_ the interrupt when not using MSI. So by all indications it seems like gmbus is able to generate a legacy (shared) interrupt in MSI mode on some configurations. I've tried to reproduce this and the differentiating thing seems to be that on unaffected systems no other device uses irq 16 (which seems to be the non-MSI intel gfx interrupt on all gm45). I have no idea how that even can happen. To avoid tempting this elephant into a rage, just disable gmbus interrupt support on gen 4. v2: Improve the commit message with exact details of what's going on. Also add a comment in the code to warn against this particular elephant in the room. v3: Move the comment explaing how gen4 blows up next to the definition of HAS_GMBUS_IRQ to keep the code-flow straight. Suggested by Chris Wilson. Signed-off-by: Jiri Kosina (v1) Acked-by: Chris Wilson References: https://lkml.org/lkml/2013/3/8/325 Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_i2c.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index acf8aec9ada7..ef4744e1bf0b 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -203,7 +203,13 @@ intel_gpio_setup(struct intel_gmbus *bus, u32 pin) algo->data = bus; } -#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 4) +/* + * gmbus on gen4 seems to be able to generate legacy interrupts even when in MSI + * mode. This results in spurious interrupt warnings if the legacy irq no. is + * shared with another device. The kernel then disables that interrupt source + * and so prevents the other device from working properly. + */ +#define HAS_GMBUS_IRQ(dev) (INTEL_INFO(dev)->gen >= 5) static int gmbus_wait_hw_status(struct drm_i915_private *dev_priv, u32 gmbus2_status, @@ -214,6 +220,9 @@ gmbus_wait_hw_status(struct drm_i915_private *dev_priv, u32 gmbus2 = 0; DEFINE_WAIT(wait); + if (!HAS_GMBUS_IRQ(dev_priv->dev)) + gmbus4_irq_en = 0; + /* Important: The hw handles only the first bit, so set only one! Since * we also need to check for NAKs besides the hw ready/idle signal, we * need to wake up periodically and check that ourselves. */ -- cgit v1.2.3 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 v1.2.3 From f002a24388cc460c8a9be7d446a9871f7c9d52b6 Mon Sep 17 00:00:00 2001 From: Nicholas Bellinger Date: Mon, 18 Mar 2013 13:15:57 -0700 Subject: target/file: Bump FD_MAX_SECTORS to 2048 to handle 1M sized I/Os This patch bumps the default FILEIO backend FD_MAX_SECTORS value from 1024 -> 2048 in order to allow block_size=512 to handle 1M sized I/Os. The current default rejects I/Os larger than 512K in sbc_parse_cdb(): [12015.915146] SCSI OP 2ah with too big sectors 1347 exceeds backend hw_max_sectors: 1024 [12015.977744] SCSI OP 2ah with too big sectors 2048 exceeds backend hw_max_sectors: 1024 This issue is present in >= v3.5 based kernels, introduced after the removal of se_task logic. Reported-by: Viljami Ilola Cc: Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_file.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h index bc02b018ae46..37ffc5bd2399 100644 --- a/drivers/target/target_core_file.h +++ b/drivers/target/target_core_file.h @@ -7,7 +7,7 @@ #define FD_DEVICE_QUEUE_DEPTH 32 #define FD_MAX_DEVICE_QUEUE_DEPTH 128 #define FD_BLOCKSIZE 512 -#define FD_MAX_SECTORS 1024 +#define FD_MAX_SECTORS 2048 #define RRF_EMULATE_CDB 0x01 #define RRF_GOT_LBA 0x02 -- cgit v1.2.3 From 8f27d487bcc2bd603c2d87e1729abcbc301f15db Mon Sep 17 00:00:00 2001 From: Asias He Date: Tue, 19 Mar 2013 12:55:16 +0800 Subject: target/pscsi: Reject cross page boundary case in pscsi_map_sg We can only have one page of data in each sg element, so we can not cross a page boundary. Fail this case. The 'while (len > 0 && data_len > 0) {}' loop is not necessary. The loop can only be executed once. Signed-off-by: Asias He Signed-off-by: Nicholas Bellinger --- drivers/target/target_core_pscsi.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 82e78d72fdb6..e992b27aa090 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -883,7 +883,14 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, pr_debug("PSCSI: i: %d page: %p len: %d off: %d\n", i, page, len, off); - while (len > 0 && data_len > 0) { + /* + * We only have one page of data in each sg element, + * we can not cross a page boundary. + */ + if (off + len > PAGE_SIZE) + goto fail; + + if (len > 0 && data_len > 0) { bytes = min_t(unsigned int, len, PAGE_SIZE - off); bytes = min(bytes, data_len); @@ -940,9 +947,7 @@ pscsi_map_sg(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents, bio = NULL; } - len -= bytes; data_len -= bytes; - off = 0; } } -- cgit v1.2.3 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 v1.2.3 From ce7d363aaf1e28be8406a2976220944ca487e8ca Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 4 Mar 2013 12:37:14 +1100 Subject: md/raid5: schedule_construction should abort if nothing to do. Since commit 1ed850f356a0a422013846b5291acff08815008b md/raid5: make sure to_read and to_write never go negative. It has been possible for handle_stripe_dirtying to be called when there isn't actually any work to do. It then calls schedule_reconstruction() which will set R5_LOCKED on the parity block(s) even when nothing else is happening. This then causes problems in do_release_stripe(). So add checks to schedule_reconstruction() so that if it doesn't find anything to do, it just aborts. This bug was introduced in v3.7, so the patch is suitable for -stable kernels since then. Cc: stable@vger.kernel.org (v3.7+) Reported-by: majianpeng Signed-off-by: NeilBrown --- drivers/md/raid5.c | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 35031c8b2d02..5601dda1bc40 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2283,17 +2283,6 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, int level = conf->level; if (rcw) { - /* if we are not expanding this is a proper write request, and - * there will be bios with new data to be drained into the - * stripe cache - */ - if (!expand) { - sh->reconstruct_state = reconstruct_state_drain_run; - set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); - } else - sh->reconstruct_state = reconstruct_state_run; - - set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); for (i = disks; i--; ) { struct r5dev *dev = &sh->dev[i]; @@ -2306,6 +2295,21 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, s->locked++; } } + /* if we are not expanding this is a proper write request, and + * there will be bios with new data to be drained into the + * stripe cache + */ + if (!expand) { + if (!s->locked) + /* False alarm, nothing to do */ + return; + sh->reconstruct_state = reconstruct_state_drain_run; + set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); + } else + sh->reconstruct_state = reconstruct_state_run; + + set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); + if (s->locked + conf->max_degraded == disks) if (!test_and_set_bit(STRIPE_FULL_WRITE, &sh->state)) atomic_inc(&conf->pending_full_writes); @@ -2314,11 +2318,6 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, BUG_ON(!(test_bit(R5_UPTODATE, &sh->dev[pd_idx].flags) || test_bit(R5_Wantcompute, &sh->dev[pd_idx].flags))); - sh->reconstruct_state = reconstruct_state_prexor_drain_run; - set_bit(STRIPE_OP_PREXOR, &s->ops_request); - set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); - set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); - for (i = disks; i--; ) { struct r5dev *dev = &sh->dev[i]; if (i == pd_idx) @@ -2333,6 +2332,13 @@ schedule_reconstruction(struct stripe_head *sh, struct stripe_head_state *s, s->locked++; } } + if (!s->locked) + /* False alarm - nothing to do */ + return; + sh->reconstruct_state = reconstruct_state_prexor_drain_run; + set_bit(STRIPE_OP_PREXOR, &s->ops_request); + set_bit(STRIPE_OP_BIODRAIN, &s->ops_request); + set_bit(STRIPE_OP_RECONSTRUCT, &s->ops_request); } /* keep the parity disk(s) locked while asynchronous operations -- cgit v1.2.3 From e3620a3ad52609f64a2402e4b59300afb4b83b77 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 7 Mar 2013 16:22:01 -0600 Subject: MD RAID5: Avoid accessing gendisk or queue structs when not available MD RAID5: Fix kernel oops when RAID4/5/6 is used via device-mapper Commit a9add5d (v3.8-rc1) added blktrace calls to the RAID4/5/6 driver. However, when device-mapper is used to create RAID4/5/6 arrays, the mddev->gendisk and mddev->queue fields are not setup. Therefore, calling things like trace_block_bio_remap will cause a kernel oops. This patch conditionalizes those calls on whether the proper fields exist to make the calls. (Device-mapper will call trace_block_bio_remap on its own.) This patch is suitable for the 3.8.y stable kernel. Cc: stable@vger.kernel.org (v3.8+) Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- drivers/md/raid5.c | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 5601dda1bc40..52ba88a10668 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -674,9 +674,11 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) bi->bi_next = NULL; if (rrdev) set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags); - trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), - bi, disk_devt(conf->mddev->gendisk), - sh->dev[i].sector); + + if (conf->mddev->gendisk) + trace_block_bio_remap(bdev_get_queue(bi->bi_bdev), + bi, disk_devt(conf->mddev->gendisk), + sh->dev[i].sector); generic_make_request(bi); } if (rrdev) { @@ -704,9 +706,10 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s) rbi->bi_io_vec[0].bv_offset = 0; rbi->bi_size = STRIPE_SIZE; rbi->bi_next = NULL; - trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), - rbi, disk_devt(conf->mddev->gendisk), - sh->dev[i].sector); + if (conf->mddev->gendisk) + trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev), + rbi, disk_devt(conf->mddev->gendisk), + sh->dev[i].sector); generic_make_request(rbi); } if (!rdev && !rrdev) { @@ -2835,8 +2838,10 @@ static void handle_stripe_dirtying(struct r5conf *conf, set_bit(STRIPE_HANDLE, &sh->state); if (rmw < rcw && rmw > 0) { /* prefer read-modify-write, but need to get some data */ - blk_add_trace_msg(conf->mddev->queue, "raid5 rmw %llu %d", - (unsigned long long)sh->sector, rmw); + if (conf->mddev->queue) + blk_add_trace_msg(conf->mddev->queue, + "raid5 rmw %llu %d", + (unsigned long long)sh->sector, rmw); for (i = disks; i--; ) { struct r5dev *dev = &sh->dev[i]; if ((dev->towrite || i == sh->pd_idx) && @@ -2886,7 +2891,7 @@ static void handle_stripe_dirtying(struct r5conf *conf, } } } - if (rcw) + if (rcw && conf->mddev->queue) blk_add_trace_msg(conf->mddev->queue, "raid5 rcw %llu %d %d %d", (unsigned long long)sh->sector, rcw, qread, test_bit(STRIPE_DELAYED, &sh->state)); @@ -3993,9 +3998,10 @@ static int chunk_aligned_read(struct mddev *mddev, struct bio * raid_bio) atomic_inc(&conf->active_aligned_reads); spin_unlock_irq(&conf->device_lock); - trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), - align_bi, disk_devt(mddev->gendisk), - raid_bio->bi_sector); + if (mddev->gendisk) + trace_block_bio_remap(bdev_get_queue(align_bi->bi_bdev), + align_bi, disk_devt(mddev->gendisk), + raid_bio->bi_sector); generic_make_request(align_bi); return 1; } else { @@ -4089,7 +4095,8 @@ static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule) } spin_unlock_irq(&conf->device_lock); } - trace_block_unplug(mddev->queue, cnt, !from_schedule); + if (mddev->queue) + trace_block_unplug(mddev->queue, cnt, !from_schedule); kfree(cb); } -- cgit v1.2.3 From 90584fc93d461520a888f691144f0879283b3624 Mon Sep 17 00:00:00 2001 From: Jonathan Brassow Date: Thu, 7 Mar 2013 16:24:26 -0600 Subject: MD: Prevent sysfs operations on uninitialized kobjects MD: Prevent sysfs operations on uninitialized kobjects Device-mapper does not use sysfs; but when device-mapper is leveraging MD's RAID personalities, MD sometimes attempts to update sysfs. This patch adds checks for 'mddev-kobj.sd' in sysfs_[un]link_rdev to ensure it is about to operate on something valid. This patch also checks for 'mddev->kobj.sd' before calling 'sysfs_notify' in 'remove_and_add_spares'. Although 'sysfs_notify' already makes this check, doing so in 'remove_and_add_spares' prevents an additional mutex operation. Signed-off-by: Jonathan Brassow Signed-off-by: NeilBrown --- drivers/md/md.c | 6 ++---- drivers/md/md.h | 4 ++-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/md.c b/drivers/md/md.c index fcb878f88796..aeceedfc530b 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -7663,10 +7663,8 @@ static int remove_and_add_spares(struct mddev *mddev) removed++; } } - if (removed) - sysfs_notify(&mddev->kobj, NULL, - "degraded"); - + if (removed && mddev->kobj.sd) + sysfs_notify(&mddev->kobj, NULL, "degraded"); rdev_for_each(rdev, mddev) { if (rdev->raid_disk >= 0 && diff --git a/drivers/md/md.h b/drivers/md/md.h index eca59c3074ef..d90fb1a879e1 100644 --- a/drivers/md/md.h +++ b/drivers/md/md.h @@ -506,7 +506,7 @@ static inline char * mdname (struct mddev * mddev) static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) { char nm[20]; - if (!test_bit(Replacement, &rdev->flags)) { + if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { sprintf(nm, "rd%d", rdev->raid_disk); return sysfs_create_link(&mddev->kobj, &rdev->kobj, nm); } else @@ -516,7 +516,7 @@ static inline int sysfs_link_rdev(struct mddev *mddev, struct md_rdev *rdev) static inline void sysfs_unlink_rdev(struct mddev *mddev, struct md_rdev *rdev) { char nm[20]; - if (!test_bit(Replacement, &rdev->flags)) { + if (!test_bit(Replacement, &rdev->flags) && mddev->kobj.sd) { sprintf(nm, "rd%d", rdev->raid_disk); sysfs_remove_link(&mddev->kobj, nm); } -- cgit v1.2.3 From f8dfcffd0472a0f353f34a567ad3f53568914d04 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Tue, 12 Mar 2013 12:18:06 +1100 Subject: md/raid5: ensure sync and DISCARD don't happen at the same time. A number of problems can occur due to races between resync/recovery and discard. - if sync_request calls handle_stripe() while a discard is happening on the stripe, it might call handle_stripe_clean_event before all of the individual discard requests have completed (so some devices are still locked, but not all). Since commit ca64cae96037de16e4af92678814f5d4bf0c1c65 md/raid5: Make sure we clear R5_Discard when discard is finished. this will cause R5_Discard to be cleared for the parity device, so handle_stripe_clean_event() will not be called when the other devices do become unlocked, so their ->written will not be cleared. This ultimately leads to a WARN_ON in init_stripe and a lock-up. - If handle_stripe_clean_event() does clear R5_UPTODATE at an awkward time for resync, it can lead to s->uptodate being less than disks in handle_parity_checks5(), which triggers a BUG (because it is one). So: - keep R5_Discard on the parity device until all other devices have completed their discard request - make sure we don't try to have a 'discard' and a 'sync' action at the same time. This involves a new stripe flag to we know when a 'discard' is happening, and the use of R5_Overlap on the parity disk so when a discard is wanted while a sync is active, so we know to wake up the discard at the appropriate time. Discard support for RAID5 was added in 3.7, so this is suitable for any -stable kernel since 3.7. Cc: stable@vger.kernel.org (v3.7+) Reported-by: Jes Sorensen Tested-by: Jes Sorensen Signed-off-by: NeilBrown --- drivers/md/raid5.c | 45 +++++++++++++++++++++++++++++++++++++++------ drivers/md/raid5.h | 1 + 2 files changed, 40 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 52ba88a10668..42a899728748 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -2576,6 +2576,8 @@ handle_failed_sync(struct r5conf *conf, struct stripe_head *sh, int i; clear_bit(STRIPE_SYNCING, &sh->state); + if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) + wake_up(&conf->wait_for_overlap); s->syncing = 0; s->replacing = 0; /* There is nothing more to do for sync/check/repair. @@ -2749,6 +2751,7 @@ static void handle_stripe_clean_event(struct r5conf *conf, { int i; struct r5dev *dev; + int discard_pending = 0; for (i = disks; i--; ) if (sh->dev[i].written) { @@ -2777,9 +2780,23 @@ static void handle_stripe_clean_event(struct r5conf *conf, STRIPE_SECTORS, !test_bit(STRIPE_DEGRADED, &sh->state), 0); - } - } else if (test_bit(R5_Discard, &sh->dev[i].flags)) - clear_bit(R5_Discard, &sh->dev[i].flags); + } else if (test_bit(R5_Discard, &dev->flags)) + discard_pending = 1; + } + if (!discard_pending && + test_bit(R5_Discard, &sh->dev[sh->pd_idx].flags)) { + clear_bit(R5_Discard, &sh->dev[sh->pd_idx].flags); + clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags); + if (sh->qd_idx >= 0) { + clear_bit(R5_Discard, &sh->dev[sh->qd_idx].flags); + clear_bit(R5_UPTODATE, &sh->dev[sh->qd_idx].flags); + } + /* now that discard is done we can proceed with any sync */ + clear_bit(STRIPE_DISCARD, &sh->state); + if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) + set_bit(STRIPE_HANDLE, &sh->state); + + } if (test_and_clear_bit(STRIPE_FULL_WRITE, &sh->state)) if (atomic_dec_and_test(&conf->pending_full_writes)) @@ -3431,9 +3448,15 @@ static void handle_stripe(struct stripe_head *sh) return; } - if (test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { - set_bit(STRIPE_SYNCING, &sh->state); - clear_bit(STRIPE_INSYNC, &sh->state); + if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { + spin_lock(&sh->stripe_lock); + /* Cannot process 'sync' concurrently with 'discard' */ + if (!test_bit(STRIPE_DISCARD, &sh->state) && + test_and_clear_bit(STRIPE_SYNC_REQUESTED, &sh->state)) { + set_bit(STRIPE_SYNCING, &sh->state); + clear_bit(STRIPE_INSYNC, &sh->state); + } + spin_unlock(&sh->stripe_lock); } clear_bit(STRIPE_DELAYED, &sh->state); @@ -3593,6 +3616,8 @@ static void handle_stripe(struct stripe_head *sh) test_bit(STRIPE_INSYNC, &sh->state)) { md_done_sync(conf->mddev, STRIPE_SECTORS, 1); clear_bit(STRIPE_SYNCING, &sh->state); + if (test_and_clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags)) + wake_up(&conf->wait_for_overlap); } /* If the failed drives are just a ReadError, then we might need @@ -4159,6 +4184,13 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi) sh = get_active_stripe(conf, logical_sector, 0, 0, 0); prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE); + set_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); + if (test_bit(STRIPE_SYNCING, &sh->state)) { + release_stripe(sh); + schedule(); + goto again; + } + clear_bit(R5_Overlap, &sh->dev[sh->pd_idx].flags); spin_lock_irq(&sh->stripe_lock); for (d = 0; d < conf->raid_disks; d++) { if (d == sh->pd_idx || d == sh->qd_idx) @@ -4171,6 +4203,7 @@ static void make_discard_request(struct mddev *mddev, struct bio *bi) goto again; } } + set_bit(STRIPE_DISCARD, &sh->state); finish_wait(&conf->wait_for_overlap, &w); for (d = 0; d < conf->raid_disks; d++) { if (d == sh->pd_idx || d == sh->qd_idx) diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 18b2c4a8a1fd..050a334e89c1 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h @@ -323,6 +323,7 @@ enum { STRIPE_COMPUTE_RUN, STRIPE_OPS_REQ_PENDING, STRIPE_ON_UNPLUG_LIST, + STRIPE_DISCARD, }; /* -- cgit v1.2.3 From 238f5908bd48f9e2f4668e0289e88cba969d710c Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Mon, 11 Mar 2013 11:27:44 +0100 Subject: md: remove CONFIG_MULTICORE_RAID456 entirely Once instance of this Kconfig macro remained after commit 51acbcec6c42b24482bac18e42befc822524535d ("md: remove CONFIG_MULTICORE_RAID456"). Remove that one too. And, while we're at it, also remove it from the defconfig files that carry it. Signed-off-by: Paul Bolle Signed-off-by: NeilBrown --- arch/tile/configs/tilegx_defconfig | 1 - arch/tile/configs/tilepro_defconfig | 1 - drivers/md/raid5.h | 4 ---- 3 files changed, 6 deletions(-) (limited to 'drivers') diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig index 8c5eff6d6df5..47684815e5c8 100644 --- a/arch/tile/configs/tilegx_defconfig +++ b/arch/tile/configs/tilegx_defconfig @@ -330,7 +330,6 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m -CONFIG_MULTICORE_RAID456=y CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m CONFIG_DM_DEBUG=y diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig index e7a3dfcbcda7..dd2b8f0c631f 100644 --- a/arch/tile/configs/tilepro_defconfig +++ b/arch/tile/configs/tilepro_defconfig @@ -324,7 +324,6 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID456=m -CONFIG_MULTICORE_RAID456=y CONFIG_MD_FAULTY=m CONFIG_BLK_DEV_DM=m CONFIG_DM_DEBUG=y diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 050a334e89c1..b0b663b119a8 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h @@ -221,10 +221,6 @@ struct stripe_head { struct stripe_operations { int target, target2; enum sum_check_flags zero_sum_result; - #ifdef CONFIG_MULTICORE_RAID456 - unsigned long request; - wait_queue_head_t wait_for_ops; - #endif } ops; struct r5dev { /* rreq and rvec are used for the replacement device when -- cgit v1.2.3 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 v1.2.3 From 5830daf8174d7ea8df2621f8dbede3096bb659b5 Mon Sep 17 00:00:00 2001 From: Vikas Sajjan Date: Wed, 27 Feb 2013 16:02:58 +0530 Subject: drm/exynos: modify the compatible string for exynos fimd modified compatible string for exynos4 fimd as "exynos4210-fimd" and exynos5 fimd as "exynos5250-fimd" to stick to the rule that compatible value should be named after first specific SoC model in which this particular IP version was included as discussed at https://patchwork.kernel.org/patch/2144861/ Signed-off-by: Vikas Sajjan Acked-by: Joonyoung Shim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 36493ce71f9a..549cb7db9c9f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -109,9 +109,9 @@ struct fimd_context { #ifdef CONFIG_OF static const struct of_device_id fimd_driver_dt_match[] = { - { .compatible = "samsung,exynos4-fimd", + { .compatible = "samsung,exynos4210-fimd", .data = &exynos4_fimd_driver_data }, - { .compatible = "samsung,exynos5-fimd", + { .compatible = "samsung,exynos5250-fimd", .data = &exynos5_fimd_driver_data }, {}, }; -- cgit v1.2.3 From 9800935a215ddf278da4860f59b4d29d2f429152 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Sat, 2 Mar 2013 15:06:24 +0530 Subject: drm/exynos: Make mixer_check_timing static Fixes the following sparse warning: drivers/gpu/drm/exynos/exynos_mixer.c:821:5: warning: symbol 'mixer_check_timing' was not declared. Should it be static? Signed-off-by: Sachin Kamat Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_mixer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index e919aba29b3d..2f4f72f07047 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -818,7 +818,7 @@ static void mixer_win_disable(void *ctx, int win) mixer_ctx->win_data[win].enabled = false; } -int mixer_check_timing(void *ctx, struct fb_videomode *timing) +static int mixer_check_timing(void *ctx, struct fb_videomode *timing) { struct mixer_context *mixer_ctx = ctx; u32 w, h; -- cgit v1.2.3 From 0f10cf1463c6fc02a9e85bf098ef3c215d94b1e3 Mon Sep 17 00:00:00 2001 From: Leela Krishna Amudala Date: Thu, 7 Mar 2013 23:28:52 -0500 Subject: drm/exynos: fimd: calculate the correct address offset Calculate the correct address offset values for alpha and color key control registers based on exynos4 and exynos5 user manuals. Also remove VIDOSD_C_SIZE_W0 macro and fix comments about registers for size and alpha. Signed-off-by: Leela Krishna Amudala Acked-by: Joonyoung Shim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_fimd.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index 549cb7db9c9f..98cc14725ba9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -38,11 +38,12 @@ /* position control register for hardware window 0, 2 ~ 4.*/ #define VIDOSD_A(win) (VIDOSD_BASE + 0x00 + (win) * 16) #define VIDOSD_B(win) (VIDOSD_BASE + 0x04 + (win) * 16) -/* size control register for hardware window 0. */ -#define VIDOSD_C_SIZE_W0 (VIDOSD_BASE + 0x08) -/* alpha control register for hardware window 1 ~ 4. */ -#define VIDOSD_C(win) (VIDOSD_BASE + 0x18 + (win) * 16) -/* size control register for hardware window 1 ~ 4. */ +/* + * size control register for hardware windows 0 and alpha control register + * for hardware windows 1 ~ 4 + */ +#define VIDOSD_C(win) (VIDOSD_BASE + 0x08 + (win) * 16) +/* size control register for hardware windows 1 ~ 2. */ #define VIDOSD_D(win) (VIDOSD_BASE + 0x0C + (win) * 16) #define VIDWx_BUF_START(win, buf) (VIDW_BUF_START(buf) + (win) * 8) @@ -50,9 +51,9 @@ #define VIDWx_BUF_SIZE(win, buf) (VIDW_BUF_SIZE(buf) + (win) * 4) /* color key control register for hardware window 1 ~ 4. */ -#define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + (x * 8)) +#define WKEYCON0_BASE(x) ((WKEYCON0 + 0x140) + ((x - 1) * 8)) /* color key value register for hardware window 1 ~ 4. */ -#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + (x * 8)) +#define WKEYCON1_BASE(x) ((WKEYCON1 + 0x140) + ((x - 1) * 8)) /* FIMD has totally five hardware windows. */ #define WINDOWS_NR 5 @@ -581,7 +582,7 @@ static void fimd_win_commit(struct device *dev, int zpos) if (win != 3 && win != 4) { u32 offset = VIDOSD_D(win); if (win == 0) - offset = VIDOSD_C_SIZE_W0; + offset = VIDOSD_C(win); val = win_data->ovl_width * win_data->ovl_height; writel(val, ctx->regs + offset); -- cgit v1.2.3 From e2779e1698c7dbf36a02a9922d216b4db0e212b8 Mon Sep 17 00:00:00 2001 From: Alexandru Gheorghiu Date: Mon, 11 Mar 2013 21:25:22 +0200 Subject: drm/exynos: Replaced kzalloc & memcpy with kmemdup Replaced calls to kzalloc followed by memcpy with call to kmemdup. Patch found using coccinelle. Signed-off-by: Alexandru Gheorghiu Acked-by: Seung-Woo Kim Signed-off-by: Inki Dae --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 13ccbd4bcfaa..9504b0cd825a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -117,13 +117,12 @@ static struct edid *vidi_get_edid(struct device *dev, } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; - edid = kzalloc(edid_len, GFP_KERNEL); + edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { DRM_DEBUG_KMS("failed to allocate edid\n"); return ERR_PTR(-ENOMEM); } - memcpy(edid, ctx->raw_edid, edid_len); return edid; } @@ -563,12 +562,11 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, return -EINVAL; } edid_len = (1 + raw_edid->extensions) * EDID_LENGTH; - ctx->raw_edid = kzalloc(edid_len, GFP_KERNEL); + ctx->raw_edid = kmemdup(raw_edid, edid_len, GFP_KERNEL); if (!ctx->raw_edid) { DRM_DEBUG_KMS("failed to allocate raw_edid.\n"); return -ENOMEM; } - memcpy(ctx->raw_edid, raw_edid, edid_len); } else { /* * with connection = 0, free raw_edid -- cgit v1.2.3 From 067ed3311f7961bef67551fa5115dbadf9a035f4 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 11 Mar 2013 19:48:05 +0900 Subject: drm/exynos: Fix error routine to getting dma addr. This patch fixes error routine when g2d_userptr_get_dma_add is failed. When sg_alloc_table_from_pages() is failed, it doesn't call sg_free_table() anymore. Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 3b0da0378acf..28b71125189b 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -450,7 +450,7 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, DMA_BIDIRECTIONAL); if (ret < 0) { DRM_ERROR("failed to map sgt with dma region.\n"); - goto err_free_sgt; + goto err_sg_free_table; } g2d_userptr->dma_addr = sgt->sgl[0].dma_address; @@ -467,8 +467,10 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev, return &g2d_userptr->dma_addr; -err_free_sgt: +err_sg_free_table: sg_free_table(sgt); + +err_free_sgt: kfree(sgt); sgt = NULL; -- cgit v1.2.3 From 5efc1d1b53ba60a89ce8269880ed02eddecd1add Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 11 Mar 2013 19:56:17 +0900 Subject: drm/exynos: clear node object type at gem unmap This patch clears node object type in G2D unmap cmdlist. The obj_type of cmdlist node has to be cleared in g2d_unmap_cmdlist_gem() so that the node can be reused in g2d_map_cmdlist_gem(). Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 28b71125189b..095520fdf5eb 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -576,6 +576,7 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, false); node->handles[i] = 0; + node->obj_type[i] = 0; } node->map_nr = 0; -- cgit v1.2.3 From 7ad018140cc9c0e3388243e524f8410e5f174658 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 13 Mar 2013 16:44:37 +0900 Subject: drm/exynos: Fix G2D core malfunctioning issue This patch fixes G2D core malfunctioning issue once g2d dma is started. Without 'DMA_HOLD_CMD_REG' register setting, there is only one interrupt after the execution to all command lists have been completed. And that induces watchdog. So this patch sets 'LIST_HOLD' command to the register so that command execution interrupt can be occured whenever each command list execution is finished. Changelog v2: - Consider for interrupt setup to each command list and all command lists And correct typo. Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 095520fdf5eb..1ff11443f552 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -82,7 +82,7 @@ #define G2D_DMA_LIST_DONE_COUNT_OFFSET 17 /* G2D_DMA_HOLD_CMD */ -#define G2D_USET_HOLD (1 << 2) +#define G2D_USER_HOLD (1 << 2) #define G2D_LIST_HOLD (1 << 1) #define G2D_BITBLT_HOLD (1 << 0) @@ -592,10 +592,6 @@ static void g2d_dma_start(struct g2d_data *g2d, pm_runtime_get_sync(g2d->dev); clk_enable(g2d->gate_clk); - /* interrupt enable */ - writel_relaxed(G2D_INTEN_ACF | G2D_INTEN_UCF | G2D_INTEN_GCF, - g2d->regs + G2D_INTEN); - writel_relaxed(node->dma_addr, g2d->regs + G2D_DMA_SFR_BASE_ADDR); writel_relaxed(G2D_DMA_START, g2d->regs + G2D_DMA_COMMAND); } @@ -863,9 +859,23 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, cmdlist->data[cmdlist->last++] = G2D_SRC_BASE_ADDR; cmdlist->data[cmdlist->last++] = 0; + /* + * 'LIST_HOLD' command should be set to the DMA_HOLD_CMD_REG + * and GCF bit should be set to INTEN register if user wants + * G2D interrupt event once current command list execution is + * finished. + * Otherwise only ACF bit should be set to INTEN register so + * that one interrupt is occured after all command lists + * have been completed. + */ if (node->event) { + cmdlist->data[cmdlist->last++] = G2D_INTEN; + cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF | G2D_INTEN_GCF; cmdlist->data[cmdlist->last++] = G2D_DMA_HOLD_CMD; cmdlist->data[cmdlist->last++] = G2D_LIST_HOLD; + } else { + cmdlist->data[cmdlist->last++] = G2D_INTEN; + cmdlist->data[cmdlist->last++] = G2D_INTEN_ACF; } /* Check size of cmdlist: last 2 is about G2D_BITBLT_START */ -- cgit v1.2.3 From f3d2fc4a7315d8dd39e6fb37122a3aa08fea6e62 Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 13 Mar 2013 16:55:48 +0900 Subject: drm/exynos: Clean up some G2D codes for readability This patch just cleans up G2D codes for readability. For this, it changes the member of g2d_cmdlist_node, obj_type into buf_type. Changelog v2: - Revert irrelevant codes. Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 1ff11443f552..7c1aac3871da 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -131,13 +131,12 @@ struct g2d_cmdlist_userptr { bool in_pool; bool out_of_list; }; - struct g2d_cmdlist_node { struct list_head list; struct g2d_cmdlist *cmdlist; unsigned int map_nr; unsigned long handles[MAX_BUF_ADDR_NR]; - unsigned int obj_type[MAX_BUF_ADDR_NR]; + unsigned int buf_type[MAX_BUF_ADDR_NR]; dma_addr_t dma_addr; struct drm_exynos_pending_g2d_event *event; @@ -524,7 +523,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, offset = cmdlist->last - (i * 2 + 1); handle = cmdlist->data[offset]; - if (node->obj_type[i] == BUF_TYPE_GEM) { + if (node->buf_type[i] == BUF_TYPE_GEM) { addr = exynos_drm_gem_get_dma_addr(drm_dev, handle, file); if (IS_ERR(addr)) { @@ -568,7 +567,7 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, for (i = 0; i < node->map_nr; i++) { unsigned long handle = node->handles[i]; - if (node->obj_type[i] == BUF_TYPE_GEM) + if (node->buf_type[i] == BUF_TYPE_GEM) exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle, filp); else @@ -576,7 +575,7 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, false); node->handles[i] = 0; - node->obj_type[i] = 0; + node->buf_type[i] = 0; } node->map_nr = 0; @@ -642,7 +641,6 @@ static void g2d_runqueue_worker(struct work_struct *work) struct g2d_data *g2d = container_of(work, struct g2d_data, runqueue_work); - mutex_lock(&g2d->runqueue_mutex); clk_disable(g2d->gate_clk); pm_runtime_put_sync(g2d->dev); @@ -730,7 +728,7 @@ static int g2d_check_reg_offset(struct device *dev, reg_offset = (cmdlist->data[index] & ~0x7fffffff) >> 31; if (reg_offset) { - node->obj_type[i] = BUF_TYPE_USERPTR; + node->buf_type[i] = BUF_TYPE_USERPTR; cmdlist->data[index] &= ~G2D_BUF_USERPTR; } } @@ -752,8 +750,8 @@ static int g2d_check_reg_offset(struct device *dev, if (!for_addr) goto err; - if (node->obj_type[i] != BUF_TYPE_USERPTR) - node->obj_type[i] = BUF_TYPE_GEM; + if (node->buf_type[i] != BUF_TYPE_USERPTR) + node->buf_type[i] = BUF_TYPE_GEM; break; default: if (for_addr) -- cgit v1.2.3 From 9963cb6ef9e6f925617b3c74f0700bf5fbee9a1d Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Wed, 13 Mar 2013 17:10:08 +0900 Subject: drm/exynos: Deal with g2d buffer info more efficiently This patch adds g2d_buf_info structure and buffer relevant variables moves into the g2d_buf_info to manage g2d buffer information more efficiently. Changelog v2: - Fix merge conflict. Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 160 ++++++++++++++++++++++++-------- 1 file changed, 123 insertions(+), 37 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 7c1aac3871da..1a022dc4188e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -96,8 +96,6 @@ #define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM) #define G2D_CMDLIST_DATA_NUM (G2D_CMDLIST_SIZE / sizeof(u32) - 2) -#define MAX_BUF_ADDR_NR 6 - /* maximum buffer pool size of userptr is 64MB as default */ #define MAX_POOL (64 * 1024 * 1024) @@ -106,6 +104,17 @@ enum { BUF_TYPE_USERPTR, }; +enum g2d_reg_type { + REG_TYPE_NONE = -1, + REG_TYPE_SRC, + REG_TYPE_SRC_PLANE2, + REG_TYPE_DST, + REG_TYPE_DST_PLANE2, + REG_TYPE_PAT, + REG_TYPE_MSK, + MAX_REG_TYPE_NR +}; + /* cmdlist data structure */ struct g2d_cmdlist { u32 head; @@ -113,6 +122,22 @@ struct g2d_cmdlist { u32 last; /* last data offset */ }; +/* + * A structure of buffer information + * + * @map_nr: manages the number of mapped buffers + * @reg_types: stores regitster type in the order of requested command + * @handles: stores buffer handle in its reg_type position + * @types: stores buffer type in its reg_type position + * + */ +struct g2d_buf_info { + unsigned int map_nr; + enum g2d_reg_type reg_types[MAX_REG_TYPE_NR]; + unsigned long handles[MAX_REG_TYPE_NR]; + unsigned int types[MAX_REG_TYPE_NR]; +}; + struct drm_exynos_pending_g2d_event { struct drm_pending_event base; struct drm_exynos_g2d_event event; @@ -134,10 +159,8 @@ struct g2d_cmdlist_userptr { struct g2d_cmdlist_node { struct list_head list; struct g2d_cmdlist *cmdlist; - unsigned int map_nr; - unsigned long handles[MAX_BUF_ADDR_NR]; - unsigned int buf_type[MAX_BUF_ADDR_NR]; dma_addr_t dma_addr; + struct g2d_buf_info buf_info; struct drm_exynos_pending_g2d_event *event; }; @@ -187,6 +210,7 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) struct exynos_drm_subdrv *subdrv = &g2d->subdrv; int nr; int ret; + struct g2d_buf_info *buf_info; init_dma_attrs(&g2d->cmdlist_dma_attrs); dma_set_attr(DMA_ATTR_WRITE_COMBINE, &g2d->cmdlist_dma_attrs); @@ -208,11 +232,17 @@ static int g2d_init_cmdlist(struct g2d_data *g2d) } for (nr = 0; nr < G2D_CMDLIST_NUM; nr++) { + unsigned int i; + node[nr].cmdlist = g2d->cmdlist_pool_virt + nr * G2D_CMDLIST_SIZE; node[nr].dma_addr = g2d->cmdlist_pool + nr * G2D_CMDLIST_SIZE; + buf_info = &node[nr].buf_info; + for (i = 0; i < MAX_REG_TYPE_NR; i++) + buf_info->reg_types[i] = REG_TYPE_NONE; + list_add_tail(&node[nr].list, &g2d->free_cmdlist); } @@ -507,36 +537,80 @@ static void g2d_userptr_free_all(struct drm_device *drm_dev, g2d->current_pool = 0; } +static enum g2d_reg_type g2d_get_reg_type(int reg_offset) +{ + enum g2d_reg_type reg_type; + + switch (reg_offset) { + case G2D_SRC_BASE_ADDR: + reg_type = REG_TYPE_SRC; + break; + case G2D_SRC_PLANE2_BASE_ADDR: + reg_type = REG_TYPE_SRC_PLANE2; + break; + case G2D_DST_BASE_ADDR: + reg_type = REG_TYPE_DST; + break; + case G2D_DST_PLANE2_BASE_ADDR: + reg_type = REG_TYPE_DST_PLANE2; + break; + case G2D_PAT_BASE_ADDR: + reg_type = REG_TYPE_PAT; + break; + case G2D_MSK_BASE_ADDR: + reg_type = REG_TYPE_MSK; + break; + default: + reg_type = REG_TYPE_NONE; + DRM_ERROR("Unknown register offset![%d]\n", reg_offset); + break; + }; + + return reg_type; +} + static int g2d_map_cmdlist_gem(struct g2d_data *g2d, struct g2d_cmdlist_node *node, struct drm_device *drm_dev, struct drm_file *file) { struct g2d_cmdlist *cmdlist = node->cmdlist; + struct g2d_buf_info *buf_info = &node->buf_info; int offset; + int ret; int i; - for (i = 0; i < node->map_nr; i++) { + for (i = 0; i < buf_info->map_nr; i++) { + enum g2d_reg_type reg_type; + int reg_pos; unsigned long handle; dma_addr_t *addr; - offset = cmdlist->last - (i * 2 + 1); - handle = cmdlist->data[offset]; + reg_pos = cmdlist->last - 2 * (i + 1); + + offset = cmdlist->data[reg_pos]; + handle = cmdlist->data[reg_pos + 1]; + + reg_type = g2d_get_reg_type(offset); + if (reg_type == REG_TYPE_NONE) { + ret = -EFAULT; + goto err; + } - if (node->buf_type[i] == BUF_TYPE_GEM) { + if (buf_info->types[reg_type] == BUF_TYPE_GEM) { addr = exynos_drm_gem_get_dma_addr(drm_dev, handle, file); if (IS_ERR(addr)) { - node->map_nr = i; - return -EFAULT; + ret = -EFAULT; + goto err; } } else { struct drm_exynos_g2d_userptr g2d_userptr; if (copy_from_user(&g2d_userptr, (void __user *)handle, sizeof(struct drm_exynos_g2d_userptr))) { - node->map_nr = i; - return -EFAULT; + ret = -EFAULT; + goto err; } addr = g2d_userptr_get_dma_addr(drm_dev, @@ -545,16 +619,21 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, file, &handle); if (IS_ERR(addr)) { - node->map_nr = i; - return -EFAULT; + ret = -EFAULT; + goto err; } } - cmdlist->data[offset] = *addr; - node->handles[i] = handle; + cmdlist->data[reg_pos + 1] = *addr; + buf_info->reg_types[i] = reg_type; + buf_info->handles[reg_type] = handle; } return 0; + +err: + buf_info->map_nr = i; + return ret; } static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, @@ -562,23 +641,30 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, struct drm_file *filp) { struct exynos_drm_subdrv *subdrv = &g2d->subdrv; + struct g2d_buf_info *buf_info = &node->buf_info; int i; - for (i = 0; i < node->map_nr; i++) { - unsigned long handle = node->handles[i]; + for (i = 0; i < buf_info->map_nr; i++) { + enum g2d_reg_type reg_type; + unsigned long handle; + + reg_type = buf_info->reg_types[i]; - if (node->buf_type[i] == BUF_TYPE_GEM) + handle = buf_info->handles[reg_type]; + + if (buf_info->types[reg_type] == BUF_TYPE_GEM) exynos_drm_gem_put_dma_addr(subdrv->drm_dev, handle, filp); else g2d_userptr_put_dma_addr(subdrv->drm_dev, handle, false); - node->handles[i] = 0; - node->buf_type[i] = 0; + buf_info->reg_types[i] = REG_TYPE_NONE; + buf_info->handles[reg_type] = 0; + buf_info->types[reg_type] = 0; } - node->map_nr = 0; + buf_info->map_nr = 0; } static void g2d_dma_start(struct g2d_data *g2d, @@ -721,20 +807,12 @@ static int g2d_check_reg_offset(struct device *dev, int i; for (i = 0; i < nr; i++) { - index = cmdlist->last - 2 * (i + 1); + struct g2d_buf_info *buf_info = &node->buf_info; + enum g2d_reg_type reg_type; - if (for_addr) { - /* check userptr buffer type. */ - reg_offset = (cmdlist->data[index] & - ~0x7fffffff) >> 31; - if (reg_offset) { - node->buf_type[i] = BUF_TYPE_USERPTR; - cmdlist->data[index] &= ~G2D_BUF_USERPTR; - } - } + index = cmdlist->last - 2 * (i + 1); reg_offset = cmdlist->data[index] & ~0xfffff000; - if (reg_offset < G2D_VALID_START || reg_offset > G2D_VALID_END) goto err; if (reg_offset % 4) @@ -750,8 +828,16 @@ static int g2d_check_reg_offset(struct device *dev, if (!for_addr) goto err; - if (node->buf_type[i] != BUF_TYPE_USERPTR) - node->buf_type[i] = BUF_TYPE_GEM; + reg_type = g2d_get_reg_type(reg_offset); + if (reg_type == REG_TYPE_NONE) + goto err; + + /* check userptr buffer type. */ + if ((cmdlist->data[index] & ~0x7fffffff) >> 31) { + buf_info->types[reg_type] = BUF_TYPE_USERPTR; + cmdlist->data[index] &= ~G2D_BUF_USERPTR; + } else + buf_info->types[reg_type] = BUF_TYPE_GEM; break; default: if (for_addr) @@ -898,7 +984,7 @@ int exynos_g2d_set_cmdlist_ioctl(struct drm_device *drm_dev, void *data, if (ret < 0) goto err_free_event; - node->map_nr = req->cmd_buf_nr; + node->buf_info.map_nr = req->cmd_buf_nr; if (req->cmd_buf_nr) { struct drm_exynos_g2d_cmd *cmd_buf; -- cgit v1.2.3 From a4f19aaab3e69f9d15cc995e3378d27c8ef4f780 Mon Sep 17 00:00:00 2001 From: Inki Dae Date: Mon, 11 Mar 2013 21:15:59 +0900 Subject: drm/exynos: Add a new function to get gem buffer size This patch adds a new function to get gem buffer size. And this funtion could be used for g2d driver or others can get gem buffer size to check if the buffer is valid or not. Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_gem.c | 21 +++++++++++++++++++++ drivers/gpu/drm/exynos/exynos_drm_gem.h | 5 +++++ 2 files changed, 26 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 67e17ce112b6..0e6fe000578c 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c @@ -164,6 +164,27 @@ out: exynos_gem_obj = NULL; } +unsigned long exynos_drm_gem_get_size(struct drm_device *dev, + unsigned int gem_handle, + struct drm_file *file_priv) +{ + struct exynos_drm_gem_obj *exynos_gem_obj; + struct drm_gem_object *obj; + + obj = drm_gem_object_lookup(dev, file_priv, gem_handle); + if (!obj) { + DRM_ERROR("failed to lookup gem object.\n"); + return 0; + } + + exynos_gem_obj = to_exynos_gem_obj(obj); + + drm_gem_object_unreference_unlocked(obj); + + return exynos_gem_obj->buffer->size; +} + + struct exynos_drm_gem_obj *exynos_drm_gem_init(struct drm_device *dev, unsigned long size) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 35ebac47dc2b..468766bee450 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h @@ -130,6 +130,11 @@ int exynos_drm_gem_userptr_ioctl(struct drm_device *dev, void *data, int exynos_drm_gem_get_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); +/* get buffer size to gem handle. */ +unsigned long exynos_drm_gem_get_size(struct drm_device *dev, + unsigned int gem_handle, + struct drm_file *file_priv); + /* initialize gem object. */ int exynos_drm_gem_init_object(struct drm_gem_object *obj); -- cgit v1.2.3 From 2dec17c70e7567f226331c26d8daa0c16d3e7e6d Mon Sep 17 00:00:00 2001 From: YoungJun Cho Date: Mon, 11 Mar 2013 21:17:52 +0900 Subject: drm/exynos: Check g2d cmd list for g2d restrictions This patch checks command list from user for g2d restrictions. For now, g2d driver wasn't considered for G2D hardware restrictions properly. The below is the restrictions to G2D hardware and this patch considers them. - width or height value in the command list has to be in valid range (1 to 8000 pixels) - The requested area should be less than buffer size. - right has to be bigger than left. - bottom has to be bigger than top. Changelog v2: - Fix merge conflict. Signed-off-by: YoungJun Cho Signed-off-by: Inki Dae Signed-off-by: Kyungmin Park --- drivers/gpu/drm/exynos/exynos_drm_g2d.c | 183 ++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/exynos/exynos_drm_g2d.c b/drivers/gpu/drm/exynos/exynos_drm_g2d.c index 1a022dc4188e..47a493c8a71f 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_g2d.c +++ b/drivers/gpu/drm/exynos/exynos_drm_g2d.c @@ -48,8 +48,14 @@ /* registers for base address */ #define G2D_SRC_BASE_ADDR 0x0304 +#define G2D_SRC_COLOR_MODE 0x030C +#define G2D_SRC_LEFT_TOP 0x0310 +#define G2D_SRC_RIGHT_BOTTOM 0x0314 #define G2D_SRC_PLANE2_BASE_ADDR 0x0318 #define G2D_DST_BASE_ADDR 0x0404 +#define G2D_DST_COLOR_MODE 0x040C +#define G2D_DST_LEFT_TOP 0x0410 +#define G2D_DST_RIGHT_BOTTOM 0x0414 #define G2D_DST_PLANE2_BASE_ADDR 0x0418 #define G2D_PAT_BASE_ADDR 0x0500 #define G2D_MSK_BASE_ADDR 0x0520 @@ -91,6 +97,22 @@ #define G2D_START_NHOLT (1 << 1) #define G2D_START_BITBLT (1 << 0) +/* buffer color format */ +#define G2D_FMT_XRGB8888 0 +#define G2D_FMT_ARGB8888 1 +#define G2D_FMT_RGB565 2 +#define G2D_FMT_XRGB1555 3 +#define G2D_FMT_ARGB1555 4 +#define G2D_FMT_XRGB4444 5 +#define G2D_FMT_ARGB4444 6 +#define G2D_FMT_PACKED_RGB888 7 +#define G2D_FMT_A8 11 +#define G2D_FMT_L8 12 + +/* buffer valid length */ +#define G2D_LEN_MIN 1 +#define G2D_LEN_MAX 8000 + #define G2D_CMDLIST_SIZE (PAGE_SIZE / 4) #define G2D_CMDLIST_NUM 64 #define G2D_CMDLIST_POOL_SIZE (G2D_CMDLIST_SIZE * G2D_CMDLIST_NUM) @@ -122,6 +144,24 @@ struct g2d_cmdlist { u32 last; /* last data offset */ }; +/* + * A structure of buffer description + * + * @format: color format + * @left_x: the x coordinates of left top corner + * @top_y: the y coordinates of left top corner + * @right_x: the x coordinates of right bottom corner + * @bottom_y: the y coordinates of right bottom corner + * + */ +struct g2d_buf_desc { + unsigned int format; + unsigned int left_x; + unsigned int top_y; + unsigned int right_x; + unsigned int bottom_y; +}; + /* * A structure of buffer information * @@ -129,6 +169,7 @@ struct g2d_cmdlist { * @reg_types: stores regitster type in the order of requested command * @handles: stores buffer handle in its reg_type position * @types: stores buffer type in its reg_type position + * @descs: stores buffer description in its reg_type position * */ struct g2d_buf_info { @@ -136,6 +177,7 @@ struct g2d_buf_info { enum g2d_reg_type reg_types[MAX_REG_TYPE_NR]; unsigned long handles[MAX_REG_TYPE_NR]; unsigned int types[MAX_REG_TYPE_NR]; + struct g2d_buf_desc descs[MAX_REG_TYPE_NR]; }; struct drm_exynos_pending_g2d_event { @@ -543,12 +585,18 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) switch (reg_offset) { case G2D_SRC_BASE_ADDR: + case G2D_SRC_COLOR_MODE: + case G2D_SRC_LEFT_TOP: + case G2D_SRC_RIGHT_BOTTOM: reg_type = REG_TYPE_SRC; break; case G2D_SRC_PLANE2_BASE_ADDR: reg_type = REG_TYPE_SRC_PLANE2; break; case G2D_DST_BASE_ADDR: + case G2D_DST_COLOR_MODE: + case G2D_DST_LEFT_TOP: + case G2D_DST_RIGHT_BOTTOM: reg_type = REG_TYPE_DST; break; case G2D_DST_PLANE2_BASE_ADDR: @@ -569,6 +617,69 @@ static enum g2d_reg_type g2d_get_reg_type(int reg_offset) return reg_type; } +static unsigned long g2d_get_buf_bpp(unsigned int format) +{ + unsigned long bpp; + + switch (format) { + case G2D_FMT_XRGB8888: + case G2D_FMT_ARGB8888: + bpp = 4; + break; + case G2D_FMT_RGB565: + case G2D_FMT_XRGB1555: + case G2D_FMT_ARGB1555: + case G2D_FMT_XRGB4444: + case G2D_FMT_ARGB4444: + bpp = 2; + break; + case G2D_FMT_PACKED_RGB888: + bpp = 3; + break; + default: + bpp = 1; + break; + } + + return bpp; +} + +static bool g2d_check_buf_desc_is_valid(struct g2d_buf_desc *buf_desc, + enum g2d_reg_type reg_type, + unsigned long size) +{ + unsigned int width, height; + unsigned long area; + + /* + * check source and destination buffers only. + * so the others are always valid. + */ + if (reg_type != REG_TYPE_SRC && reg_type != REG_TYPE_DST) + return true; + + width = buf_desc->right_x - buf_desc->left_x; + if (width < G2D_LEN_MIN || width > G2D_LEN_MAX) { + DRM_ERROR("width[%u] is out of range!\n", width); + return false; + } + + height = buf_desc->bottom_y - buf_desc->top_y; + if (height < G2D_LEN_MIN || height > G2D_LEN_MAX) { + DRM_ERROR("height[%u] is out of range!\n", height); + return false; + } + + area = (unsigned long)width * (unsigned long)height * + g2d_get_buf_bpp(buf_desc->format); + if (area > size) { + DRM_ERROR("area[%lu] is out of range[%lu]!\n", area, size); + return false; + } + + return true; +} + static int g2d_map_cmdlist_gem(struct g2d_data *g2d, struct g2d_cmdlist_node *node, struct drm_device *drm_dev, @@ -581,6 +692,7 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, int i; for (i = 0; i < buf_info->map_nr; i++) { + struct g2d_buf_desc *buf_desc; enum g2d_reg_type reg_type; int reg_pos; unsigned long handle; @@ -597,7 +709,23 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, goto err; } + buf_desc = &buf_info->descs[reg_type]; + if (buf_info->types[reg_type] == BUF_TYPE_GEM) { + unsigned long size; + + size = exynos_drm_gem_get_size(drm_dev, handle, file); + if (!size) { + ret = -EFAULT; + goto err; + } + + if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type, + size)) { + ret = -EFAULT; + goto err; + } + addr = exynos_drm_gem_get_dma_addr(drm_dev, handle, file); if (IS_ERR(addr)) { @@ -613,6 +741,12 @@ static int g2d_map_cmdlist_gem(struct g2d_data *g2d, goto err; } + if (!g2d_check_buf_desc_is_valid(buf_desc, reg_type, + g2d_userptr.size)) { + ret = -EFAULT; + goto err; + } + addr = g2d_userptr_get_dma_addr(drm_dev, g2d_userptr.userptr, g2d_userptr.size, @@ -645,11 +779,13 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, int i; for (i = 0; i < buf_info->map_nr; i++) { + struct g2d_buf_desc *buf_desc; enum g2d_reg_type reg_type; unsigned long handle; reg_type = buf_info->reg_types[i]; + buf_desc = &buf_info->descs[reg_type]; handle = buf_info->handles[reg_type]; if (buf_info->types[reg_type] == BUF_TYPE_GEM) @@ -662,6 +798,7 @@ static void g2d_unmap_cmdlist_gem(struct g2d_data *g2d, buf_info->reg_types[i] = REG_TYPE_NONE; buf_info->handles[reg_type] = 0; buf_info->types[reg_type] = 0; + memset(buf_desc, 0x00, sizeof(*buf_desc)); } buf_info->map_nr = 0; @@ -808,7 +945,9 @@ static int g2d_check_reg_offset(struct device *dev, for (i = 0; i < nr; i++) { struct g2d_buf_info *buf_info = &node->buf_info; + struct g2d_buf_desc *buf_desc; enum g2d_reg_type reg_type; + unsigned long value; index = cmdlist->last - 2 * (i + 1); @@ -839,6 +978,50 @@ static int g2d_check_reg_offset(struct device *dev, } else buf_info->types[reg_type] = BUF_TYPE_GEM; break; + case G2D_SRC_COLOR_MODE: + case G2D_DST_COLOR_MODE: + if (for_addr) + goto err; + + reg_type = g2d_get_reg_type(reg_offset); + if (reg_type == REG_TYPE_NONE) + goto err; + + buf_desc = &buf_info->descs[reg_type]; + value = cmdlist->data[index + 1]; + + buf_desc->format = value & 0xf; + break; + case G2D_SRC_LEFT_TOP: + case G2D_DST_LEFT_TOP: + if (for_addr) + goto err; + + reg_type = g2d_get_reg_type(reg_offset); + if (reg_type == REG_TYPE_NONE) + goto err; + + buf_desc = &buf_info->descs[reg_type]; + value = cmdlist->data[index + 1]; + + buf_desc->left_x = value & 0x1fff; + buf_desc->top_y = (value & 0x1fff0000) >> 16; + break; + case G2D_SRC_RIGHT_BOTTOM: + case G2D_DST_RIGHT_BOTTOM: + if (for_addr) + goto err; + + reg_type = g2d_get_reg_type(reg_offset); + if (reg_type == REG_TYPE_NONE) + goto err; + + buf_desc = &buf_info->descs[reg_type]; + value = cmdlist->data[index + 1]; + + buf_desc->right_x = value & 0x1fff; + buf_desc->bottom_y = (value & 0x1fff0000) >> 16; + break; default: if (for_addr) goto err; -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 From 699412d951e6dd4dec48db88f33dc27b361582f0 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 18 Mar 2013 10:14:47 +0200 Subject: usb: gadget: net22xx: fix ->disconnect reporting with the latest udc_start/udc_stop conversion, too much code was deleted which ended up creating a regression in net2272 and net2280 drivers. To fix the regression we revert one hunk of the original commits. Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 7 +++++++ drivers/usb/gadget/net2280.c | 7 +++++++ 2 files changed, 14 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index d226058e3b88..17628337c6b0 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -1495,6 +1495,13 @@ stop_activity(struct net2272 *dev, struct usb_gadget_driver *driver) for (i = 0; i < 4; ++i) net2272_dequeue_all(&dev->ep[i]); + /* report disconnect; the driver is already quiesced */ + if (driver) { + spin_unlock(&dev->lock); + driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + net2272_usb_reinit(dev); } diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index a1b650e11339..3105a4d601c8 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -1946,6 +1946,13 @@ stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver) for (i = 0; i < 7; i++) nuke (&dev->ep [i]); + /* report disconnect; the driver is already quiesced */ + if (driver) { + spin_unlock(&dev->lock); + driver->disconnect(&dev->gadget); + spin_lock(&dev->lock); + } + usb_reinit (dev); } -- cgit v1.2.3 From 511f3c5326eabe1ece35202a404c24c0aeacc246 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 15 Mar 2013 14:02:14 -0400 Subject: usb: gadget: udc-core: fix a regression during gadget driver unbinding This patch (as1666) fixes a regression in the UDC core. The core takes care of unbinding gadget drivers, and it does the unbinding before telling the UDC driver to turn off the controller hardware. When the call to the udc_stop callback is made, the gadget no longer has a driver. The callback routine should not be invoked with a pointer to the old driver; doing so can cause problems (such as use-after-free accesses in net2280). This patch should be applied, with appropriate context changes, to all the stable kernels going back to 3.1. Signed-off-by: Alan Stern CC: 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 2a9cd369f71c..f8f62c3ed65e 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c @@ -216,7 +216,7 @@ static void usb_gadget_remove_driver(struct usb_udc *udc) usb_gadget_disconnect(udc->gadget); udc->driver->disconnect(udc->gadget); udc->driver->unbind(udc->gadget); - usb_gadget_udc_stop(udc->gadget, udc->driver); + usb_gadget_udc_stop(udc->gadget, NULL); udc->driver = NULL; udc->dev.driver = NULL; -- cgit v1.2.3 From 8119b55aed818e590c26cb97706c914e3d660fd8 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 15 Mar 2013 14:03:17 -0400 Subject: USB: gadget: net2280: remove leftover driver->unbind call in error pathway This patch (as1667) removes an incorrect driver->unbind() call from the net2280 driver. If startup fails, the UDC core takes care of unbinding the gadget driver automatically; the controller driver shouldn't do it too. Signed-off-by: Alan Stern Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2280.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 3105a4d601c8..3bd0f992fb49 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -1924,7 +1924,6 @@ static int net2280_start(struct usb_gadget *_gadget, 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; -- cgit v1.2.3 From 3416905ba058e43112ad7b1b4859797f027f5a07 Mon Sep 17 00:00:00 2001 From: Andrzej Pietrasiewicz Date: Mon, 11 Mar 2013 16:32:14 +0100 Subject: usb: gadget: ffs: fix enable multiple instances This patch fixes an "off-by-one" bug found in 581791f (FunctionFS: enable multiple functions). During gfs_bind/gfs_unbind the functionfs_bind/functionfs_unbind should be called for every functionfs instance. With the "i" pre-decremented they were not called for the zeroth instance. Acked-by: Michal Nazarewicz Signed-off-by: Andrzej Pietrasiewicz Signed-off-by: Kyungmin Park Cc: [ balbi@ti.com : added offending commit's subject ] Signed-off-by: Felipe Balbi --- drivers/usb/gadget/g_ffs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/g_ffs.c b/drivers/usb/gadget/g_ffs.c index 3953dd4d7186..3b343b23e4b0 100644 --- a/drivers/usb/gadget/g_ffs.c +++ b/drivers/usb/gadget/g_ffs.c @@ -357,7 +357,7 @@ static int gfs_bind(struct usb_composite_dev *cdev) goto error; gfs_dev_desc.iProduct = gfs_strings[USB_GADGET_PRODUCT_IDX].id; - for (i = func_num; --i; ) { + for (i = func_num; i--; ) { ret = functionfs_bind(ffs_tab[i].ffs_data, cdev); if (unlikely(ret < 0)) { while (++i < func_num) @@ -413,7 +413,7 @@ static int gfs_unbind(struct usb_composite_dev *cdev) gether_cleanup(); gfs_ether_setup = false; - for (i = func_num; --i; ) + for (i = func_num; i--; ) if (ffs_tab[i].ffs_data) functionfs_unbind(ffs_tab[i].ffs_data); -- cgit v1.2.3 From 967baed40eaaf6df632b7e929b903140a9744b87 Mon Sep 17 00:00:00 2001 From: Truls Bengtsson Date: Wed, 20 Mar 2013 14:02:25 +0100 Subject: usb: gadget: f_rndis: Avoid to use ERROR macro if cdev can be null The udc_irq service runs the isr_tr_complete_handler which in turn "nukes" the endpoints, including a call to rndis_response_complete, if appropriate. If the rndis_msg_parser fails here, an error will be printed using a dev_err call (through the ERROR() macro). However, if the usb cable was just disconnected the device (cdev) might not be available and will be null. Since the dev_err macro will dereference the cdev pointer we get a null pointer exception. Reviewed-by: Radovan Lekanovic Signed-off-by: Truls Bengtsson Signed-off-by: Oskar Andero Acked-by: Michal Nazarewicz Signed-off-by: Felipe Balbi --- drivers/usb/gadget/f_rndis.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 71beeb833558..cc9c49c57c80 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c @@ -447,14 +447,13 @@ static void rndis_response_complete(struct usb_ep *ep, struct usb_request *req) 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", + pr_err("RNDIS command error %d, %d/%d\n", status, req->actual, req->length); // spin_unlock(&dev->lock); } -- cgit v1.2.3 From 0582b7d15f8a7ae53dd2128b8eb01567b3fd2277 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 19 Mar 2013 13:40:23 +0000 Subject: sh_eth: fix bitbang memory leak sh_mdio_init() allocates pointer to 'struct bb_info' but only stores it locally, so that sh_mdio_release() can't free it on driver unload. Add the pointer to 'struct bb_info' to 'struct sh_eth_private', so that sh_mdio_init() can save 'bitbang' variable for sh_mdio_release() to be able to free it later... Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 5 +++++ drivers/net/ethernet/renesas/sh_eth.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 33e96176e4d8..c87862812ead 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2220,6 +2220,7 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp) /* MDIO bus release function */ static int sh_mdio_release(struct net_device *ndev) { + struct sh_eth_private *mdp = netdev_priv(ndev); struct mii_bus *bus = dev_get_drvdata(&ndev->dev); /* unregister mdio bus */ @@ -2234,6 +2235,9 @@ static int sh_mdio_release(struct net_device *ndev) /* free bitbang info */ free_mdio_bitbang(bus); + /* free bitbang memory */ + kfree(mdp->bitbang); + return 0; } @@ -2262,6 +2266,7 @@ static int sh_mdio_init(struct net_device *ndev, int id, bitbang->ctrl.ops = &bb_ops; /* MII controller setting */ + mdp->bitbang = bitbang; mdp->mii_bus = alloc_mdio_bitbang(&bitbang->ctrl); if (!mdp->mii_bus) { ret = -ENOMEM; diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h index bae84fd2e73a..e6655678458e 100644 --- a/drivers/net/ethernet/renesas/sh_eth.h +++ b/drivers/net/ethernet/renesas/sh_eth.h @@ -705,6 +705,7 @@ struct sh_eth_private { const u16 *reg_offset; void __iomem *addr; void __iomem *tsu_addr; + struct bb_info *bitbang; u32 num_rx_ring; u32 num_tx_ring; dma_addr_t rx_desc_dma; -- cgit v1.2.3 From fc0c0900408e05758a0df17c1924ca837fafca5e Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Tue, 19 Mar 2013 13:41:32 +0000 Subject: sh_eth: check TSU registers ioremap() error One must check the result of ioremap() -- in this case it prevents potential kernel oops when initializing TSU registers further on... Signed-off-by: Sergei Shtylyov Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index c87862812ead..bf5e3cf97c4d 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2446,6 +2446,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev) } mdp->tsu_addr = ioremap(rtsu->start, resource_size(rtsu)); + if (mdp->tsu_addr == NULL) { + ret = -ENOMEM; + dev_err(&pdev->dev, "TSU ioremap failed.\n"); + goto out_release; + } mdp->port = devno % 2; ndev->features = NETIF_F_HW_VLAN_FILTER; } -- cgit v1.2.3 From fa90b077d72b4ea92706e86fdff7b5dca294caa3 Mon Sep 17 00:00:00 2001 From: Wei Yongjun Date: Wed, 20 Mar 2013 02:21:48 +0000 Subject: lpc_eth: fix error return code in lpc_eth_drv_probe() Fix to return a negative error code from the error handling case instead of 0, as returned elsewhere in this function. Signed-off-by: Wei Yongjun Signed-off-by: David S. Miller --- drivers/net/ethernet/nxp/lpc_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index c4122c86f829..efa29b712d5f 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c @@ -1472,7 +1472,8 @@ static int lpc_eth_drv_probe(struct platform_device *pdev) } platform_set_drvdata(pdev, ndev); - if (lpc_mii_init(pldat) != 0) + ret = lpc_mii_init(pldat); + if (ret) goto err_out_unregister_netdev; netdev_info(ndev, "LPC mac at 0x%08x irq %d\n", -- cgit v1.2.3 From da2191e31409d1058dcbed44e8f53e39a40e86b3 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 20 Mar 2013 12:31:07 -0300 Subject: net: fec: Define indexes as 'unsigned int' Fix the following warnings that happen when building with W=1 option: drivers/net/ethernet/freescale/fec.c: In function 'fec_enet_free_buffers': drivers/net/ethernet/freescale/fec.c:1337:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] drivers/net/ethernet/freescale/fec.c: In function 'fec_enet_alloc_buffers': drivers/net/ethernet/freescale/fec.c:1361:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] drivers/net/ethernet/freescale/fec.c: In function 'fec_enet_init': drivers/net/ethernet/freescale/fec.c:1631:16: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index e3f39372ce25..911d0253dbb2 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -1332,7 +1332,7 @@ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd) static void fec_enet_free_buffers(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - int i; + unsigned int i; struct sk_buff *skb; struct bufdesc *bdp; @@ -1356,7 +1356,7 @@ static void fec_enet_free_buffers(struct net_device *ndev) static int fec_enet_alloc_buffers(struct net_device *ndev) { struct fec_enet_private *fep = netdev_priv(ndev); - int i; + unsigned int i; struct sk_buff *skb; struct bufdesc *bdp; @@ -1598,7 +1598,7 @@ static int fec_enet_init(struct net_device *ndev) struct fec_enet_private *fep = netdev_priv(ndev); struct bufdesc *cbd_base; struct bufdesc *bdp; - int i; + unsigned int i; /* Allocate memory for buffer descriptors. */ cbd_base = dma_alloc_coherent(NULL, PAGE_SIZE, &fep->bd_dma, -- cgit v1.2.3 From f046f89a99ccfd9408b94c653374ff3065c7edb3 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 20 Mar 2013 17:21:24 +0000 Subject: dm thin: fix discard corruption Fix a bug in dm_btree_remove that could leave leaf values with incorrect reference counts. The effect of this was that removal of a shared block could result in the space maps thinking the block was no longer used. More concretely, if you have a thin device and a snapshot of it, sending a discard to a shared region of the thin could corrupt the snapshot. Thinp uses a 2-level nested btree to store it's mappings. This first level is indexed by thin device, and the second level by logical block. Often when we're removing an entry in this mapping tree we need to rebalance nodes, which can involve shadowing them, possibly creating a copy if the block is shared. If we do create a copy then children of that node need to have their reference counts incremented. In this way reference counts percolate down the tree as shared trees diverge. The rebalance functions were incrementing the children at the appropriate time, but they were always assuming the children were internal nodes. This meant the leaf values (in our case packed block/flags entries) were not being incremented. Cc: stable@vger.kernel.org Signed-off-by: Joe Thornber Signed-off-by: Alasdair G Kergon --- drivers/md/dm-thin.c | 4 +-- drivers/md/persistent-data/dm-btree-remove.c | 46 +++++++++++++++------------- 2 files changed, 26 insertions(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index 009339d62828..ab95e5ff3758 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -2544,7 +2544,7 @@ static struct target_type pool_target = { .name = "thin-pool", .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | DM_TARGET_IMMUTABLE, - .version = {1, 6, 1}, + .version = {1, 7, 0}, .module = THIS_MODULE, .ctr = pool_ctr, .dtr = pool_dtr, @@ -2831,7 +2831,7 @@ static int thin_iterate_devices(struct dm_target *ti, static struct target_type thin_target = { .name = "thin", - .version = {1, 7, 1}, + .version = {1, 8, 0}, .module = THIS_MODULE, .ctr = thin_ctr, .dtr = thin_dtr, diff --git a/drivers/md/persistent-data/dm-btree-remove.c b/drivers/md/persistent-data/dm-btree-remove.c index c4f28133ef82..b88757cd0d1d 100644 --- a/drivers/md/persistent-data/dm-btree-remove.c +++ b/drivers/md/persistent-data/dm-btree-remove.c @@ -139,15 +139,8 @@ struct child { struct btree_node *n; }; -static struct dm_btree_value_type le64_type = { - .context = NULL, - .size = sizeof(__le64), - .inc = NULL, - .dec = NULL, - .equal = NULL -}; - -static int init_child(struct dm_btree_info *info, struct btree_node *parent, +static int init_child(struct dm_btree_info *info, struct dm_btree_value_type *vt, + struct btree_node *parent, unsigned index, struct child *result) { int r, inc; @@ -164,7 +157,7 @@ static int init_child(struct dm_btree_info *info, struct btree_node *parent, result->n = dm_block_data(result->block); if (inc) - inc_children(info->tm, result->n, &le64_type); + inc_children(info->tm, result->n, vt); *((__le64 *) value_ptr(parent, index)) = cpu_to_le64(dm_block_location(result->block)); @@ -236,7 +229,7 @@ static void __rebalance2(struct dm_btree_info *info, struct btree_node *parent, } static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info, - unsigned left_index) + struct dm_btree_value_type *vt, unsigned left_index) { int r; struct btree_node *parent; @@ -244,11 +237,11 @@ static int rebalance2(struct shadow_spine *s, struct dm_btree_info *info, parent = dm_block_data(shadow_current(s)); - r = init_child(info, parent, left_index, &left); + r = init_child(info, vt, parent, left_index, &left); if (r) return r; - r = init_child(info, parent, left_index + 1, &right); + r = init_child(info, vt, parent, left_index + 1, &right); if (r) { exit_child(info, &left); return r; @@ -368,7 +361,7 @@ static void __rebalance3(struct dm_btree_info *info, struct btree_node *parent, } static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info, - unsigned left_index) + struct dm_btree_value_type *vt, unsigned left_index) { int r; struct btree_node *parent = dm_block_data(shadow_current(s)); @@ -377,17 +370,17 @@ static int rebalance3(struct shadow_spine *s, struct dm_btree_info *info, /* * FIXME: fill out an array? */ - r = init_child(info, parent, left_index, &left); + r = init_child(info, vt, parent, left_index, &left); if (r) return r; - r = init_child(info, parent, left_index + 1, ¢er); + r = init_child(info, vt, parent, left_index + 1, ¢er); if (r) { exit_child(info, &left); return r; } - r = init_child(info, parent, left_index + 2, &right); + r = init_child(info, vt, parent, left_index + 2, &right); if (r) { exit_child(info, &left); exit_child(info, ¢er); @@ -434,7 +427,8 @@ static int get_nr_entries(struct dm_transaction_manager *tm, } static int rebalance_children(struct shadow_spine *s, - struct dm_btree_info *info, uint64_t key) + struct dm_btree_info *info, + struct dm_btree_value_type *vt, uint64_t key) { int i, r, has_left_sibling, has_right_sibling; uint32_t child_entries; @@ -472,13 +466,13 @@ static int rebalance_children(struct shadow_spine *s, has_right_sibling = i < (le32_to_cpu(n->header.nr_entries) - 1); if (!has_left_sibling) - r = rebalance2(s, info, i); + r = rebalance2(s, info, vt, i); else if (!has_right_sibling) - r = rebalance2(s, info, i - 1); + r = rebalance2(s, info, vt, i - 1); else - r = rebalance3(s, info, i - 1); + r = rebalance3(s, info, vt, i - 1); return r; } @@ -529,7 +523,7 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info, if (le32_to_cpu(n->header.flags) & LEAF_NODE) return do_leaf(n, key, index); - r = rebalance_children(s, info, key); + r = rebalance_children(s, info, vt, key); if (r) break; @@ -550,6 +544,14 @@ static int remove_raw(struct shadow_spine *s, struct dm_btree_info *info, return r; } +static struct dm_btree_value_type le64_type = { + .context = NULL, + .size = sizeof(__le64), + .inc = NULL, + .dec = NULL, + .equal = NULL +}; + int dm_btree_remove(struct dm_btree_info *info, dm_block_t root, uint64_t *keys, dm_block_t *new_root) { -- cgit v1.2.3 From 58051b94e05a59c4d34f9f1a441af40894817c59 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 20 Mar 2013 17:21:25 +0000 Subject: dm thin: fix non power of two discard granularity calc Fix a discard granularity calculation to work for non power of 2 block sizes. In order for thinp to passdown discard bios to the underlying data device, the data device must have a discard granularity that is a factor of the thinp block size. Originally this check was done by using bitops since the block_size was known to be a power of two. Introduced by commit f13945d75730081830b6f3360266950e2b7c9067 ("dm thin: support a non power of 2 discard_granularity"). Signed-off-by: Joe Thornber Signed-off-by: Alasdair G Kergon --- drivers/md/dm-thin.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ab95e5ff3758..004ad1652b73 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c @@ -1577,6 +1577,11 @@ static bool data_dev_supports_discard(struct pool_c *pt) return q && blk_queue_discard(q); } +static bool is_factor(sector_t block_size, uint32_t n) +{ + return !sector_div(block_size, n); +} + /* * If discard_passdown was enabled verify that the data device * supports discards. Disable discard_passdown if not. @@ -1602,7 +1607,7 @@ static void disable_passdown_if_not_supported(struct pool_c *pt) else if (data_limits->discard_granularity > block_size) reason = "discard granularity larger than a block"; - else if (block_size & (data_limits->discard_granularity - 1)) + else if (!is_factor(block_size, data_limits->discard_granularity)) reason = "discard granularity not a factor of block size"; if (reason) { -- cgit v1.2.3 From 3b6b7813b198b578aa7e04e4047ddb8225c37b7f Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Wed, 20 Mar 2013 17:21:25 +0000 Subject: dm verity: avoid deadlock A deadlock was found in the prefetch code in the dm verity map function. This patch fixes this by transferring the prefetch to a worker thread and skipping it completely if kmalloc fails. If generic_make_request is called recursively, it queues the I/O request on the current->bio_list without making the I/O request and returns. The routine making the recursive call cannot wait for the I/O to complete. The deadlock occurs when one thread grabs the bufio_client mutex and waits for an I/O to complete but the I/O is queued on another thread's current->bio_list and is waiting to get the mutex held by the first thread. The fix recognises that prefetching is not essential. If memory can be allocated, it queues the prefetch request to the worker thread, but if not, it does nothing. Signed-off-by: Paul Taysom Signed-off-by: Mikulas Patocka Signed-off-by: Alasdair G Kergon Cc: stable@kernel.org --- drivers/md/dm-bufio.c | 2 ++ drivers/md/dm-verity.c | 39 ++++++++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-bufio.c b/drivers/md/dm-bufio.c index 3c955e10a618..c6083132c4b8 100644 --- a/drivers/md/dm-bufio.c +++ b/drivers/md/dm-bufio.c @@ -1025,6 +1025,8 @@ void dm_bufio_prefetch(struct dm_bufio_client *c, { struct blk_plug plug; + BUG_ON(dm_bufio_in_request()); + blk_start_plug(&plug); dm_bufio_lock(c); diff --git a/drivers/md/dm-verity.c b/drivers/md/dm-verity.c index 6ad538375c3c..a746f1d21c66 100644 --- a/drivers/md/dm-verity.c +++ b/drivers/md/dm-verity.c @@ -93,6 +93,13 @@ struct dm_verity_io { */ }; +struct dm_verity_prefetch_work { + struct work_struct work; + struct dm_verity *v; + sector_t block; + unsigned n_blocks; +}; + static struct shash_desc *io_hash_desc(struct dm_verity *v, struct dm_verity_io *io) { return (struct shash_desc *)(io + 1); @@ -424,15 +431,18 @@ static void verity_end_io(struct bio *bio, int error) * The root buffer is not prefetched, it is assumed that it will be cached * all the time. */ -static void verity_prefetch_io(struct dm_verity *v, struct dm_verity_io *io) +static void verity_prefetch_io(struct work_struct *work) { + struct dm_verity_prefetch_work *pw = + container_of(work, struct dm_verity_prefetch_work, work); + struct dm_verity *v = pw->v; int i; for (i = v->levels - 2; i >= 0; i--) { sector_t hash_block_start; sector_t hash_block_end; - verity_hash_at_level(v, io->block, i, &hash_block_start, NULL); - verity_hash_at_level(v, io->block + io->n_blocks - 1, i, &hash_block_end, NULL); + verity_hash_at_level(v, pw->block, i, &hash_block_start, NULL); + verity_hash_at_level(v, pw->block + pw->n_blocks - 1, i, &hash_block_end, NULL); if (!i) { unsigned cluster = ACCESS_ONCE(dm_verity_prefetch_cluster); @@ -452,6 +462,25 @@ no_prefetch_cluster: dm_bufio_prefetch(v->bufio, hash_block_start, hash_block_end - hash_block_start + 1); } + + kfree(pw); +} + +static void verity_submit_prefetch(struct dm_verity *v, struct dm_verity_io *io) +{ + struct dm_verity_prefetch_work *pw; + + pw = kmalloc(sizeof(struct dm_verity_prefetch_work), + GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); + + if (!pw) + return; + + INIT_WORK(&pw->work, verity_prefetch_io); + pw->v = v; + pw->block = io->block; + pw->n_blocks = io->n_blocks; + queue_work(v->verify_wq, &pw->work); } /* @@ -498,7 +527,7 @@ static int verity_map(struct dm_target *ti, struct bio *bio) memcpy(io->io_vec, bio_iovec(bio), io->io_vec_size * sizeof(struct bio_vec)); - verity_prefetch_io(v, io); + verity_submit_prefetch(v, io); generic_make_request(bio); @@ -858,7 +887,7 @@ bad: static struct target_type verity_target = { .name = "verity", - .version = {1, 1, 1}, + .version = {1, 2, 0}, .module = THIS_MODULE, .ctr = verity_ctr, .dtr = verity_dtr, -- cgit v1.2.3 From 414dd67d50a6b9a11af23bbb68e8fae13d726c8b Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 20 Mar 2013 17:21:25 +0000 Subject: dm cache: avoid 64 bit division on 32 bit Squash various 32bit link errors. >> on i386: >> drivers/built-in.o: In function `is_discarded_oblock': >> dm-cache-target.c:(.text+0x1ea28e): undefined reference to `__udivdi3' ... Reported-by: Randy Dunlap Signed-off-by: Joe Thornber Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-target.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 0f4e84b15c30..5ad227f0cea3 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -158,7 +158,7 @@ struct cache { /* * origin_blocks entries, discarded if set. */ - sector_t discard_block_size; /* a power of 2 times sectors per block */ + uint32_t discard_block_size; /* a power of 2 times sectors per block */ dm_dblock_t discard_nr_blocks; unsigned long *discard_bitset; @@ -412,17 +412,24 @@ static bool block_size_is_power_of_two(struct cache *cache) return cache->sectors_per_block_shift >= 0; } +static dm_block_t block_div(dm_block_t b, uint32_t n) +{ + do_div(b, n); + + return b; +} + static dm_dblock_t oblock_to_dblock(struct cache *cache, dm_oblock_t oblock) { - sector_t discard_blocks = cache->discard_block_size; + uint32_t discard_blocks = cache->discard_block_size; dm_block_t b = from_oblock(oblock); if (!block_size_is_power_of_two(cache)) - (void) sector_div(discard_blocks, cache->sectors_per_block); + discard_blocks = discard_blocks / cache->sectors_per_block; else discard_blocks >>= cache->sectors_per_block_shift; - (void) sector_div(b, discard_blocks); + b = block_div(b, discard_blocks); return to_dblock(b); } @@ -1002,7 +1009,7 @@ static void process_discard_bio(struct cache *cache, struct bio *bio) dm_block_t end_block = bio->bi_sector + bio_sectors(bio); dm_block_t b; - (void) sector_div(end_block, cache->discard_block_size); + end_block = block_div(end_block, cache->discard_block_size); for (b = start_block; b < end_block; b++) set_discard(cache, to_dblock(b)); @@ -1835,7 +1842,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) /* FIXME: factor out this whole section */ origin_blocks = cache->origin_sectors = ca->origin_sectors; - (void) sector_div(origin_blocks, ca->block_size); + origin_blocks = block_div(origin_blocks, ca->block_size); cache->origin_blocks = to_oblock(origin_blocks); cache->sectors_per_block = ca->block_size; @@ -1848,7 +1855,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) dm_block_t cache_size = ca->cache_sectors; cache->sectors_per_block_shift = -1; - (void) sector_div(cache_size, ca->block_size); + cache_size = block_div(cache_size, ca->block_size); cache->cache_size = to_cblock(cache_size); } else { cache->sectors_per_block_shift = __ffs(ca->block_size); -- cgit v1.2.3 From 617a0b89da4898d4cc990c9eb4bc9c0591c538a5 Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Wed, 20 Mar 2013 17:21:26 +0000 Subject: dm cache: detect cache_create failure Return error if cache_create() fails. A missing return check made cache_ctr continue even after an error in cache_create() resulting in the cache object being destroyed. So a simple failure like an odd number of cache policy config value arguments would result in an oops. Signed-off-by: Heinz Mauelshagen Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-target.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 5ad227f0cea3..76cc910557f0 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2009,6 +2009,8 @@ static int cache_ctr(struct dm_target *ti, unsigned argc, char **argv) goto out; r = cache_create(ca, &cache); + if (r) + goto out; r = copy_ctr_args(cache, argc - 3, (const char **)argv + 3); if (r) { -- cgit v1.2.3 From b978440b8db901aba0c4cd38c7c841c9b5cd9a7e Mon Sep 17 00:00:00 2001 From: Heinz Mauelshagen Date: Wed, 20 Mar 2013 17:21:26 +0000 Subject: dm cache: avoid calling policy destructor twice on error If the cache policy's config values are not able to be set we must set the policy to NULL after destroying it in create_cache_policy() so we don't attempt to destroy it a second time later. Signed-off-by: Heinz Mauelshagen Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-target.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 76cc910557f0..79ac8603644d 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -1763,8 +1763,11 @@ static int create_cache_policy(struct cache *cache, struct cache_args *ca, } r = set_config_values(cache->policy, ca->policy_argc, ca->policy_argv); - if (r) + if (r) { + *error = "Error setting cache policy's config values"; dm_cache_policy_destroy(cache->policy); + cache->policy = NULL; + } return r; } -- cgit v1.2.3 From 79ed9caffc9fff67aa64fd683e791aa70f1bcb51 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 20 Mar 2013 17:21:27 +0000 Subject: dm cache: metadata clear dirty bits on clean shutdown When writing the dirty bitset to the metadata device on a clean shutdown, clear the dirty bits. Previously they were left indicating the cache was dirty. This led to confusion about whether there really was dirty data in the cache or not. (This was a harmless bug.) Reported-by: Darrick J. Wong Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-metadata.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index fbd3625f2748..1bb91802b22a 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -979,7 +979,7 @@ static int __dirty(struct dm_cache_metadata *cmd, dm_cblock_t cblock, bool dirty /* nothing to be done */ return 0; - value = pack_value(oblock, flags | (dirty ? M_DIRTY : 0)); + value = pack_value(oblock, (flags & ~M_DIRTY) | (dirty ? M_DIRTY : 0)); __dm_bless_for_disk(&value); r = dm_array_set_value(&cmd->info, cmd->root, from_cblock(cblock), -- cgit v1.2.3 From e2e74d617eadc15f601983270c4f4a6935c5a943 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Wed, 20 Mar 2013 17:21:27 +0000 Subject: dm cache: fix race in writethrough implementation We have found a race in the optimisation used in the dm cache writethrough implementation. Currently, dm core sends the cache target two bios, one for the origin device and one for the cache device and these are processed in parallel. This patch avoids the race by changing the code back to a simpler (slower) implementation which processes the two writes in series, one after the other, until we can develop a complete fix for the problem. When the cache is in writethrough mode it needs to send WRITE bios to both the origin and cache devices. Previously we've been implementing this by having dm core query the cache target on every write to find out how many copies of the bio it wants. The cache will ask for two bios if the block is in the cache, and one otherwise. Then main problem with this is it's racey. At the time this check is made the bio hasn't yet been submitted and so isn't being taken into account when quiescing a block for migration (promotion or demotion). This means a single bio may be submitted when two were needed because the block has since been promoted to the cache (catastrophic), or two bios where only one is needed (harmless). I really don't want to start entering bios into the quiescing system (deferred_set) in the get_num_write_bios callback. Instead this patch simplifies things; only one bio is submitted by the core, this is first written to the origin and then the cache device in series. Obviously this will have a latency impact. deferred_writethrough_bios is introduced to record bios that must be later issued to the cache device from the worker thread. This deferred submission, after the origin bio completes, is required given that we're in interrupt context (writethrough_endio). Signed-off-by: Joe Thornber Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-target.c | 138 +++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 50 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index 79ac8603644d..ff267db60025 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -142,6 +142,7 @@ struct cache { spinlock_t lock; struct bio_list deferred_bios; struct bio_list deferred_flush_bios; + struct bio_list deferred_writethrough_bios; struct list_head quiesced_migrations; struct list_head completed_migrations; struct list_head need_commit_migrations; @@ -199,6 +200,11 @@ struct per_bio_data { bool tick:1; unsigned req_nr:2; struct dm_deferred_entry *all_io_entry; + + /* writethrough fields */ + struct cache *cache; + dm_cblock_t cblock; + bio_end_io_t *saved_bi_end_io; }; struct dm_cache_migration { @@ -616,6 +622,56 @@ static void issue(struct cache *cache, struct bio *bio) spin_unlock_irqrestore(&cache->lock, flags); } +static void defer_writethrough_bio(struct cache *cache, struct bio *bio) +{ + unsigned long flags; + + spin_lock_irqsave(&cache->lock, flags); + bio_list_add(&cache->deferred_writethrough_bios, bio); + spin_unlock_irqrestore(&cache->lock, flags); + + wake_worker(cache); +} + +static void writethrough_endio(struct bio *bio, int err) +{ + struct per_bio_data *pb = get_per_bio_data(bio); + bio->bi_end_io = pb->saved_bi_end_io; + + if (err) { + bio_endio(bio, err); + return; + } + + remap_to_cache(pb->cache, bio, pb->cblock); + + /* + * We can't issue this bio directly, since we're in interrupt + * context. So it get's put on a bio list for processing by the + * worker thread. + */ + defer_writethrough_bio(pb->cache, bio); +} + +/* + * When running in writethrough mode we need to send writes to clean blocks + * to both the cache and origin devices. In future we'd like to clone the + * bio and send them in parallel, but for now we're doing them in + * series as this is easier. + */ +static void remap_to_origin_then_cache(struct cache *cache, struct bio *bio, + dm_oblock_t oblock, dm_cblock_t cblock) +{ + struct per_bio_data *pb = get_per_bio_data(bio); + + pb->cache = cache; + pb->cblock = cblock; + pb->saved_bi_end_io = bio->bi_end_io; + bio->bi_end_io = writethrough_endio; + + remap_to_origin_clear_discard(pb->cache, bio, oblock); +} + /*---------------------------------------------------------------- * Migration processing * @@ -1077,14 +1133,9 @@ static void process_bio(struct cache *cache, struct prealloc *structs, inc_hit_counter(cache, bio); pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); - if (is_writethrough_io(cache, bio, lookup_result.cblock)) { - /* - * No need to mark anything dirty in write through mode. - */ - pb->req_nr == 0 ? - remap_to_cache(cache, bio, lookup_result.cblock) : - remap_to_origin_clear_discard(cache, bio, block); - } else + if (is_writethrough_io(cache, bio, lookup_result.cblock)) + remap_to_origin_then_cache(cache, bio, block, lookup_result.cblock); + else remap_to_cache_dirty(cache, bio, block, lookup_result.cblock); issue(cache, bio); @@ -1093,17 +1144,8 @@ static void process_bio(struct cache *cache, struct prealloc *structs, case POLICY_MISS: inc_miss_counter(cache, bio); pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); - - if (pb->req_nr != 0) { - /* - * This is a duplicate writethrough io that is no - * longer needed because the block has been demoted. - */ - bio_endio(bio, 0); - } else { - remap_to_origin_clear_discard(cache, bio, block); - issue(cache, bio); - } + remap_to_origin_clear_discard(cache, bio, block); + issue(cache, bio); break; case POLICY_NEW: @@ -1224,6 +1266,23 @@ static void process_deferred_flush_bios(struct cache *cache, bool submit_bios) submit_bios ? generic_make_request(bio) : bio_io_error(bio); } +static void process_deferred_writethrough_bios(struct cache *cache) +{ + unsigned long flags; + struct bio_list bios; + struct bio *bio; + + bio_list_init(&bios); + + spin_lock_irqsave(&cache->lock, flags); + bio_list_merge(&bios, &cache->deferred_writethrough_bios); + bio_list_init(&cache->deferred_writethrough_bios); + spin_unlock_irqrestore(&cache->lock, flags); + + while ((bio = bio_list_pop(&bios))) + generic_make_request(bio); +} + static void writeback_some_dirty_blocks(struct cache *cache) { int r = 0; @@ -1320,6 +1379,7 @@ static int more_work(struct cache *cache) else return !bio_list_empty(&cache->deferred_bios) || !bio_list_empty(&cache->deferred_flush_bios) || + !bio_list_empty(&cache->deferred_writethrough_bios) || !list_empty(&cache->quiesced_migrations) || !list_empty(&cache->completed_migrations) || !list_empty(&cache->need_commit_migrations); @@ -1338,6 +1398,8 @@ static void do_worker(struct work_struct *ws) writeback_some_dirty_blocks(cache); + process_deferred_writethrough_bios(cache); + if (commit_if_needed(cache)) { process_deferred_flush_bios(cache, false); @@ -1803,8 +1865,6 @@ static sector_t calculate_discard_block_size(sector_t cache_block_size, #define DEFAULT_MIGRATION_THRESHOLD (2048 * 100) -static unsigned cache_num_write_bios(struct dm_target *ti, struct bio *bio); - static int cache_create(struct cache_args *ca, struct cache **result) { int r = 0; @@ -1831,9 +1891,6 @@ static int cache_create(struct cache_args *ca, struct cache **result) memcpy(&cache->features, &ca->features, sizeof(cache->features)); - if (cache->features.write_through) - ti->num_write_bios = cache_num_write_bios; - cache->callbacks.congested_fn = cache_is_congested; dm_table_add_target_callbacks(ti->table, &cache->callbacks); @@ -1883,6 +1940,7 @@ static int cache_create(struct cache_args *ca, struct cache **result) spin_lock_init(&cache->lock); bio_list_init(&cache->deferred_bios); bio_list_init(&cache->deferred_flush_bios); + bio_list_init(&cache->deferred_writethrough_bios); INIT_LIST_HEAD(&cache->quiesced_migrations); INIT_LIST_HEAD(&cache->completed_migrations); INIT_LIST_HEAD(&cache->need_commit_migrations); @@ -2028,20 +2086,6 @@ out: return r; } -static unsigned cache_num_write_bios(struct dm_target *ti, struct bio *bio) -{ - int r; - struct cache *cache = ti->private; - dm_oblock_t block = get_bio_block(cache, bio); - dm_cblock_t cblock; - - r = policy_lookup(cache->policy, block, &cblock); - if (r < 0) - return 2; /* assume the worst */ - - return (!r && !is_dirty(cache, cblock)) ? 2 : 1; -} - static int cache_map(struct dm_target *ti, struct bio *bio) { struct cache *cache = ti->private; @@ -2109,18 +2153,12 @@ static int cache_map(struct dm_target *ti, struct bio *bio) inc_hit_counter(cache, bio); pb->all_io_entry = dm_deferred_entry_inc(cache->all_io_ds); - if (is_writethrough_io(cache, bio, lookup_result.cblock)) { - /* - * No need to mark anything dirty in write through mode. - */ - pb->req_nr == 0 ? - remap_to_cache(cache, bio, lookup_result.cblock) : - remap_to_origin_clear_discard(cache, bio, block); - cell_defer(cache, cell, false); - } else { + if (is_writethrough_io(cache, bio, lookup_result.cblock)) + remap_to_origin_then_cache(cache, bio, block, lookup_result.cblock); + else remap_to_cache_dirty(cache, bio, block, lookup_result.cblock); - cell_defer(cache, cell, false); - } + + cell_defer(cache, cell, false); break; case POLICY_MISS: @@ -2547,7 +2585,7 @@ static void cache_io_hints(struct dm_target *ti, struct queue_limits *limits) static struct target_type cache_target = { .name = "cache", - .version = {1, 0, 0}, + .version = {1, 1, 0}, .module = THIS_MODULE, .ctr = cache_ctr, .dtr = cache_dtr, -- cgit v1.2.3 From 4e7f506f6429636115e2f58f9f97089acc62524a Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Wed, 20 Mar 2013 17:21:27 +0000 Subject: dm cache: policy change version from string to integer set Separate dm cache policy version string into 3 unsigned numbers corresponding to major, minor and patchlevel and store them at the end of the on-disk metadata so we know which version of the policy generated the hints in case a future version wants to use them differently. Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-metadata.c | 15 +++++++++++++-- drivers/md/dm-cache-policy-cleaner.c | 7 +++++-- drivers/md/dm-cache-policy-internal.h | 2 ++ drivers/md/dm-cache-policy-mq.c | 8 ++++++-- drivers/md/dm-cache-policy.c | 8 ++++++++ drivers/md/dm-cache-policy.h | 2 ++ 6 files changed, 36 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 1bb91802b22a..74213d1f1db5 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -83,6 +83,8 @@ struct cache_disk_superblock { __le32 read_misses; __le32 write_hits; __le32 write_misses; + + __le32 policy_version[CACHE_POLICY_VERSION_SIZE]; } __packed; struct dm_cache_metadata { @@ -109,6 +111,7 @@ struct dm_cache_metadata { bool clean_when_opened:1; char policy_name[CACHE_POLICY_NAME_SIZE]; + unsigned policy_version[CACHE_POLICY_VERSION_SIZE]; size_t policy_hint_size; struct dm_cache_statistics stats; }; @@ -268,7 +271,8 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd) memset(disk_super->uuid, 0, sizeof(disk_super->uuid)); disk_super->magic = cpu_to_le64(CACHE_SUPERBLOCK_MAGIC); disk_super->version = cpu_to_le32(CACHE_VERSION); - memset(disk_super->policy_name, 0, CACHE_POLICY_NAME_SIZE); + memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name)); + memset(disk_super->policy_version, 0, sizeof(disk_super->policy_version)); disk_super->policy_hint_size = 0; r = dm_sm_copy_root(cmd->metadata_sm, &disk_super->metadata_space_map_root, @@ -284,7 +288,6 @@ static int __write_initial_superblock(struct dm_cache_metadata *cmd) disk_super->metadata_block_size = cpu_to_le32(DM_CACHE_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); disk_super->data_block_size = cpu_to_le32(cmd->data_block_size); disk_super->cache_blocks = cpu_to_le32(0); - memset(disk_super->policy_name, 0, sizeof(disk_super->policy_name)); disk_super->read_hits = cpu_to_le32(0); disk_super->read_misses = cpu_to_le32(0); @@ -478,6 +481,9 @@ static void read_superblock_fields(struct dm_cache_metadata *cmd, cmd->data_block_size = le32_to_cpu(disk_super->data_block_size); cmd->cache_blocks = to_cblock(le32_to_cpu(disk_super->cache_blocks)); strncpy(cmd->policy_name, disk_super->policy_name, sizeof(cmd->policy_name)); + cmd->policy_version[0] = le32_to_cpu(disk_super->policy_version[0]); + cmd->policy_version[1] = le32_to_cpu(disk_super->policy_version[1]); + cmd->policy_version[2] = le32_to_cpu(disk_super->policy_version[2]); cmd->policy_hint_size = le32_to_cpu(disk_super->policy_hint_size); cmd->stats.read_hits = le32_to_cpu(disk_super->read_hits); @@ -572,6 +578,9 @@ static int __commit_transaction(struct dm_cache_metadata *cmd, disk_super->discard_nr_blocks = cpu_to_le64(from_dblock(cmd->discard_nr_blocks)); disk_super->cache_blocks = cpu_to_le32(from_cblock(cmd->cache_blocks)); strncpy(disk_super->policy_name, cmd->policy_name, sizeof(disk_super->policy_name)); + disk_super->policy_version[0] = cpu_to_le32(cmd->policy_version[0]); + disk_super->policy_version[1] = cpu_to_le32(cmd->policy_version[1]); + disk_super->policy_version[2] = cpu_to_le32(cmd->policy_version[2]); disk_super->read_hits = cpu_to_le32(cmd->stats.read_hits); disk_super->read_misses = cpu_to_le32(cmd->stats.read_misses); @@ -1070,6 +1079,7 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po __le32 value; size_t hint_size; const char *policy_name = dm_cache_policy_get_name(policy); + const unsigned *policy_version = dm_cache_policy_get_version(policy); if (!policy_name[0] || (strlen(policy_name) > sizeof(cmd->policy_name) - 1)) @@ -1077,6 +1087,7 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po if (strcmp(cmd->policy_name, policy_name)) { strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name)); + memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version)); hint_size = dm_cache_policy_get_hint_size(policy); if (!hint_size) diff --git a/drivers/md/dm-cache-policy-cleaner.c b/drivers/md/dm-cache-policy-cleaner.c index cc05d70b3cb8..b04d1f904d07 100644 --- a/drivers/md/dm-cache-policy-cleaner.c +++ b/drivers/md/dm-cache-policy-cleaner.c @@ -17,7 +17,6 @@ /*----------------------------------------------------------------*/ #define DM_MSG_PREFIX "cache cleaner" -#define CLEANER_VERSION "1.0.0" /* Cache entry struct. */ struct wb_cache_entry { @@ -434,6 +433,7 @@ static struct dm_cache_policy *wb_create(dm_cblock_t cache_size, static struct dm_cache_policy_type wb_policy_type = { .name = "cleaner", + .version = {1, 0, 0}, .hint_size = 0, .owner = THIS_MODULE, .create = wb_create @@ -446,7 +446,10 @@ static int __init wb_init(void) if (r < 0) DMERR("register failed %d", r); else - DMINFO("version " CLEANER_VERSION " loaded"); + DMINFO("version %u.%u.%u loaded", + wb_policy_type.version[0], + wb_policy_type.version[1], + wb_policy_type.version[2]); return r; } diff --git a/drivers/md/dm-cache-policy-internal.h b/drivers/md/dm-cache-policy-internal.h index 52a75beeced5..0928abdc49f0 100644 --- a/drivers/md/dm-cache-policy-internal.h +++ b/drivers/md/dm-cache-policy-internal.h @@ -117,6 +117,8 @@ void dm_cache_policy_destroy(struct dm_cache_policy *p); */ const char *dm_cache_policy_get_name(struct dm_cache_policy *p); +const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p); + size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p); /*----------------------------------------------------------------*/ diff --git a/drivers/md/dm-cache-policy-mq.c b/drivers/md/dm-cache-policy-mq.c index 964153255076..dc112a7137fe 100644 --- a/drivers/md/dm-cache-policy-mq.c +++ b/drivers/md/dm-cache-policy-mq.c @@ -14,7 +14,6 @@ #include #define DM_MSG_PREFIX "cache-policy-mq" -#define MQ_VERSION "1.0.0" static struct kmem_cache *mq_entry_cache; @@ -1133,6 +1132,7 @@ bad_cache_alloc: static struct dm_cache_policy_type mq_policy_type = { .name = "mq", + .version = {1, 0, 0}, .hint_size = 4, .owner = THIS_MODULE, .create = mq_create @@ -1140,6 +1140,7 @@ static struct dm_cache_policy_type mq_policy_type = { static struct dm_cache_policy_type default_policy_type = { .name = "default", + .version = {1, 0, 0}, .hint_size = 4, .owner = THIS_MODULE, .create = mq_create @@ -1164,7 +1165,10 @@ static int __init mq_init(void) r = dm_cache_policy_register(&default_policy_type); if (!r) { - DMINFO("version " MQ_VERSION " loaded"); + DMINFO("version %u.%u.%u loaded", + mq_policy_type.version[0], + mq_policy_type.version[1], + mq_policy_type.version[2]); return 0; } diff --git a/drivers/md/dm-cache-policy.c b/drivers/md/dm-cache-policy.c index 2cbf5fdaac52..21c03c570c06 100644 --- a/drivers/md/dm-cache-policy.c +++ b/drivers/md/dm-cache-policy.c @@ -150,6 +150,14 @@ const char *dm_cache_policy_get_name(struct dm_cache_policy *p) } EXPORT_SYMBOL_GPL(dm_cache_policy_get_name); +const unsigned *dm_cache_policy_get_version(struct dm_cache_policy *p) +{ + struct dm_cache_policy_type *t = p->private; + + return t->version; +} +EXPORT_SYMBOL_GPL(dm_cache_policy_get_version); + size_t dm_cache_policy_get_hint_size(struct dm_cache_policy *p) { struct dm_cache_policy_type *t = p->private; diff --git a/drivers/md/dm-cache-policy.h b/drivers/md/dm-cache-policy.h index f0f51b260544..558bdfdabf5f 100644 --- a/drivers/md/dm-cache-policy.h +++ b/drivers/md/dm-cache-policy.h @@ -196,6 +196,7 @@ struct dm_cache_policy { * We maintain a little register of the different policy types. */ #define CACHE_POLICY_NAME_SIZE 16 +#define CACHE_POLICY_VERSION_SIZE 3 struct dm_cache_policy_type { /* For use by the register code only. */ @@ -206,6 +207,7 @@ struct dm_cache_policy_type { * what gets passed on the target line to select your policy. */ char name[CACHE_POLICY_NAME_SIZE]; + unsigned version[CACHE_POLICY_VERSION_SIZE]; /* * Policies may store a hint for each each cache block. -- cgit v1.2.3 From ea2dd8c1ed0becee9812cf0840a9cd553ed398fe Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Wed, 20 Mar 2013 17:21:28 +0000 Subject: dm cache: policy ignore hints if generated by different version When reading the dm cache metadata from disk, ignore the policy hints unless they were generated by the same major version number of the same policy module. The hints are considered to be private data belonging to the specific module that generated them and there is no requirement for them to make sense to different versions of the policy that generated them. Policy modules are all required to work fine if no previous hints are supplied (or if existing hints are lost). Signed-off-by: Mike Snitzer Signed-off-by: Alasdair G Kergon --- drivers/md/dm-cache-metadata.c | 47 +++++++++++++++++++++++++++++++++--------- drivers/md/dm-cache-metadata.h | 2 +- drivers/md/dm-cache-target.c | 3 +-- 3 files changed, 39 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-cache-metadata.c b/drivers/md/dm-cache-metadata.c index 74213d1f1db5..83e995fece88 100644 --- a/drivers/md/dm-cache-metadata.c +++ b/drivers/md/dm-cache-metadata.c @@ -863,18 +863,43 @@ struct thunk { bool hints_valid; }; +static bool policy_unchanged(struct dm_cache_metadata *cmd, + struct dm_cache_policy *policy) +{ + const char *policy_name = dm_cache_policy_get_name(policy); + const unsigned *policy_version = dm_cache_policy_get_version(policy); + size_t policy_hint_size = dm_cache_policy_get_hint_size(policy); + + /* + * Ensure policy names match. + */ + if (strncmp(cmd->policy_name, policy_name, sizeof(cmd->policy_name))) + return false; + + /* + * Ensure policy major versions match. + */ + if (cmd->policy_version[0] != policy_version[0]) + return false; + + /* + * Ensure policy hint sizes match. + */ + if (cmd->policy_hint_size != policy_hint_size) + return false; + + return true; +} + static bool hints_array_initialized(struct dm_cache_metadata *cmd) { return cmd->hint_root && cmd->policy_hint_size; } static bool hints_array_available(struct dm_cache_metadata *cmd, - const char *policy_name) + struct dm_cache_policy *policy) { - bool policy_names_match = !strncmp(cmd->policy_name, policy_name, - sizeof(cmd->policy_name)); - - return cmd->clean_when_opened && policy_names_match && + return cmd->clean_when_opened && policy_unchanged(cmd, policy) && hints_array_initialized(cmd); } @@ -908,7 +933,8 @@ static int __load_mapping(void *context, uint64_t cblock, void *leaf) return r; } -static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_name, +static int __load_mappings(struct dm_cache_metadata *cmd, + struct dm_cache_policy *policy, load_mapping_fn fn, void *context) { struct thunk thunk; @@ -918,18 +944,19 @@ static int __load_mappings(struct dm_cache_metadata *cmd, const char *policy_nam thunk.cmd = cmd; thunk.respect_dirty_flags = cmd->clean_when_opened; - thunk.hints_valid = hints_array_available(cmd, policy_name); + thunk.hints_valid = hints_array_available(cmd, policy); return dm_array_walk(&cmd->info, cmd->root, __load_mapping, &thunk); } -int dm_cache_load_mappings(struct dm_cache_metadata *cmd, const char *policy_name, +int dm_cache_load_mappings(struct dm_cache_metadata *cmd, + struct dm_cache_policy *policy, load_mapping_fn fn, void *context) { int r; down_read(&cmd->root_lock); - r = __load_mappings(cmd, policy_name, fn, context); + r = __load_mappings(cmd, policy, fn, context); up_read(&cmd->root_lock); return r; @@ -1085,7 +1112,7 @@ static int begin_hints(struct dm_cache_metadata *cmd, struct dm_cache_policy *po (strlen(policy_name) > sizeof(cmd->policy_name) - 1)) return -EINVAL; - if (strcmp(cmd->policy_name, policy_name)) { + if (!policy_unchanged(cmd, policy)) { strncpy(cmd->policy_name, policy_name, sizeof(cmd->policy_name)); memcpy(cmd->policy_version, policy_version, sizeof(cmd->policy_version)); diff --git a/drivers/md/dm-cache-metadata.h b/drivers/md/dm-cache-metadata.h index 135864ea0eee..f45cef21f3d0 100644 --- a/drivers/md/dm-cache-metadata.h +++ b/drivers/md/dm-cache-metadata.h @@ -89,7 +89,7 @@ typedef int (*load_mapping_fn)(void *context, dm_oblock_t oblock, dm_cblock_t cblock, bool dirty, uint32_t hint, bool hint_valid); int dm_cache_load_mappings(struct dm_cache_metadata *cmd, - const char *policy_name, + struct dm_cache_policy *policy, load_mapping_fn fn, void *context); diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c index ff267db60025..66120bd46d15 100644 --- a/drivers/md/dm-cache-target.c +++ b/drivers/md/dm-cache-target.c @@ -2369,8 +2369,7 @@ static int cache_preresume(struct dm_target *ti) } if (!cache->loaded_mappings) { - r = dm_cache_load_mappings(cache->cmd, - dm_cache_policy_get_name(cache->policy), + r = dm_cache_load_mappings(cache->cmd, cache->policy, load_mapping, cache); if (r) { DMERR("could not load cache mappings"); -- cgit v1.2.3 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 v1.2.3 From 9d73adf431e093b23fb4990f1ade11283cb67a98 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 20 Mar 2013 08:19:32 +0000 Subject: fec: Fix the build as module Since commit ff43da86c69 (NET: FEC: dynamtic check DMA desc buff type) the following build error happens when CONFIG_FEC=m ERROR: "fec_ptp_init" [drivers/net/ethernet/freescale/fec.ko] undefined! ERROR: "fec_ptp_ioctl" [drivers/net/ethernet/freescale/fec.ko] undefined! ERROR: "fec_ptp_start_cyclecounter" [drivers/net/ethernet/freescale/fec.ko] undefined! Fix it by exporting the required fec_ptp symbols. Reported-by: Uwe Kleine-Koenig Signed-off-by: Fabio Estevam Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_ptp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c index 1f17ca0f2201..0d8df400a479 100644 --- a/drivers/net/ethernet/freescale/fec_ptp.c +++ b/drivers/net/ethernet/freescale/fec_ptp.c @@ -128,6 +128,7 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev) spin_unlock_irqrestore(&fep->tmreg_lock, flags); } +EXPORT_SYMBOL(fec_ptp_start_cyclecounter); /** * fec_ptp_adjfreq - adjust ptp cycle frequency @@ -318,6 +319,7 @@ int fec_ptp_ioctl(struct net_device *ndev, struct ifreq *ifr, int cmd) return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } +EXPORT_SYMBOL(fec_ptp_ioctl); /** * fec_time_keep - call timecounter_read every second to avoid timer overrun @@ -383,3 +385,4 @@ void fec_ptp_init(struct net_device *ndev, struct platform_device *pdev) pr_info("registered PHC device on %s\n", ndev->name); } } +EXPORT_SYMBOL(fec_ptp_init); -- cgit v1.2.3 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 v1.2.3 From d714aaf649460cbfd5e82e75520baa856b4fa0a0 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 20 Mar 2013 15:07:26 -0400 Subject: USB: EHCI: fix regression in QH unlinking This patch (as1670) fixes a regression caused by commit 6402c796d3b4205d3d7296157956c5100a05d7d6 (USB: EHCI: work around silicon bug in Intel's EHCI controllers). The workaround goes through two IAA cycles for each QH being unlinked. During the first cycle, the QH is not added to the async_iaa list (because it isn't fully gone from the hardware yet), which means that list will be empty. Unfortunately, I forgot to update the IAA watchdog timer routine. It thinks that an empty async_iaa list means the timer expiration was an error, which isn't true any more. This problem didn't show up during initial testing because the controllers being tested all had working IAA interrupts. But not all controllers do, and when the watchdog timer expires, the empty-list check prevents the second IAA cycle from starting. As a result, URB unlinks never complete. The check needs to be removed. Among the symptoms of the regression are processes stuck in D wait states and hangs during system shutdown. Signed-off-by: Alan Stern Reported-and-tested-by: Stephen Warren Reported-and-tested-by: Sven Joachim Reported-by: Andreas Bombe Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-timer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-timer.c b/drivers/usb/host/ehci-timer.c index 20dbdcbe9b0f..c3fa1305f830 100644 --- a/drivers/usb/host/ehci-timer.c +++ b/drivers/usb/host/ehci-timer.c @@ -304,7 +304,7 @@ 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) { + if (1) { u32 cmd, status; /* If we get here, IAA is *REALLY* late. It's barely -- cgit v1.2.3 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 v1.2.3 From 260b3f1291a75a580d22ce8bfb1499c617272716 Mon Sep 17 00:00:00 2001 From: Julia Lemire Date: Mon, 18 Mar 2013 10:17:47 -0400 Subject: drm/mgag200: Bug fix: Modified pll algorithm for EH project While testing the mgag200 kms driver on the HP ProLiant Gen8, a bug was seen. Once the bootloader would load the selected kernel, the screen would go black. At first it was assumed that the mgag200 kms driver was hanging. But after setting up the grub serial output, it was seen that the driver was being loaded properly. After trying serval monitors, one finaly displayed the message "Frequency Out of Range". By comparing the kms pll algorithm with the previous mgag200 xorg driver pll algorithm, discrepencies were found. Once the kms pll algorithm was modified, the expected pll values were produced. This fix was tested on several monitors of varying native resolutions. Signed-off-by: Julia Lemire Cc: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/mgag200/mgag200_mode.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a274b9906ef8..fe22bb780e1d 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c @@ -382,19 +382,19 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) m = n = p = 0; vcomax = 800000; vcomin = 400000; - pllreffreq = 3333; + pllreffreq = 33333; delta = 0xffffffff; permitteddelta = clock * 5 / 1000; - for (testp = 16; testp > 0; testp--) { + for (testp = 16; testp > 0; testp >>= 1) { if (clock * testp > vcomax) continue; if (clock * testp < vcomin) continue; for (testm = 1; testm < 33; testm++) { - for (testn = 1; testn < 257; testn++) { + for (testn = 17; testn < 257; testn++) { computed = (pllreffreq * testn) / (testm * testp); if (computed > clock) @@ -404,11 +404,11 @@ static int mga_g200eh_set_plls(struct mga_device *mdev, long clock) if (tmpdelta < delta) { delta = tmpdelta; n = testn - 1; - m = (testm - 1) | ((n >> 1) & 0x80); + m = (testm - 1); p = testp - 1; } if ((clock * testp) >= 600000) - p |= 80; + p |= 0x80; } } } -- cgit v1.2.3 From 991155bacb91c988c45586525771758ddadd44ce Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Wed, 20 Mar 2013 16:31:38 +0200 Subject: Revert "crypto: talitos - add IPsec ESN support" This reverts commit e763eb699be723fb41af818118068c6b3afdaf8d. Current IPsec ESN implementation for authencesn(cbc(aes), hmac(sha)) (separate encryption and integrity algorithms) does not conform to RFC4303. ICV is generated by hashing the sequence SPI, SeqNum-High, SeqNum-Low, IV, Payload instead of SPI, SeqNum-Low, IV, Payload, SeqNum-High. Cc: # 3.8, 3.7 Reported-by: Chaoxing Lin Signed-off-by: Horia Geanta Reviewed-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/talitos.c | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index 09b184adf31b..5b2b5e61e4f9 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -1974,11 +1973,7 @@ struct talitos_alg_template { }; static struct talitos_alg_template driver_algs[] = { - /* - * AEAD algorithms. These use a single-pass ipsec_esp descriptor. - * authencesn(*,*) is also registered, although not present - * explicitly here. - */ + /* AEAD algorithms. These use a single-pass ipsec_esp descriptor */ { .type = CRYPTO_ALG_TYPE_AEAD, .alg.crypto = { .cra_name = "authenc(hmac(sha1),cbc(aes))", @@ -2820,9 +2815,7 @@ static int talitos_probe(struct platform_device *ofdev) if (hw_supports(dev, driver_algs[i].desc_hdr_template)) { struct talitos_crypto_alg *t_alg; char *name = NULL; - bool authenc = false; -authencesn: t_alg = talitos_alg_alloc(dev, &driver_algs[i]); if (IS_ERR(t_alg)) { err = PTR_ERR(t_alg); @@ -2837,8 +2830,6 @@ authencesn: err = crypto_register_alg( &t_alg->algt.alg.crypto); name = t_alg->algt.alg.crypto.cra_driver_name; - authenc = authenc ? !authenc : - !(bool)memcmp(name, "authenc", 7); break; case CRYPTO_ALG_TYPE_AHASH: err = crypto_register_ahash( @@ -2851,25 +2842,8 @@ authencesn: dev_err(dev, "%s alg registration failed\n", name); kfree(t_alg); - } else { + } else list_add_tail(&t_alg->entry, &priv->alg_list); - if (authenc) { - struct crypto_alg *alg = - &driver_algs[i].alg.crypto; - - name = alg->cra_name; - memmove(name + 10, name + 7, - strlen(name) - 7); - memcpy(name + 7, "esn", 3); - - name = alg->cra_driver_name; - memmove(name + 10, name + 7, - strlen(name) - 7); - memcpy(name + 7, "esn", 3); - - goto authencesn; - } - } } } if (!list_empty(&priv->alg_list)) -- cgit v1.2.3 From 246bbedb9aaf27e2207501d93a869023a439fce5 Mon Sep 17 00:00:00 2001 From: Horia Geanta Date: Wed, 20 Mar 2013 16:31:58 +0200 Subject: Revert "crypto: caam - add IPsec ESN support" This reverts commit 891104ed008e8646c7860fe5bc70b0aac55dcc6c. Current IPsec ESN implementation for authencesn(cbc(aes), hmac(sha)) (separate encryption and integrity algorithms) does not conform to RFC4303. ICV is generated by hashing the sequence SPI, SeqNum-High, SeqNum-Low, IV, Payload instead of SPI, SeqNum-Low, IV, Payload, SeqNum-High. Cc: # 3.8, 3.7 Reported-by: Chaoxing Lin Signed-off-by: Horia Geanta Reviewed-by: Kim Phillips Signed-off-by: Herbert Xu --- drivers/crypto/caam/caamalg.c | 27 ++------------------------- drivers/crypto/caam/compat.h | 1 - 2 files changed, 2 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c index b2a0a0726a54..cf268b14ae9a 100644 --- a/drivers/crypto/caam/caamalg.c +++ b/drivers/crypto/caam/caamalg.c @@ -1650,11 +1650,7 @@ struct caam_alg_template { }; static struct caam_alg_template driver_algs[] = { - /* - * single-pass ipsec_esp descriptor - * authencesn(*,*) is also registered, although not present - * explicitly here. - */ + /* single-pass ipsec_esp descriptor */ { .name = "authenc(hmac(md5),cbc(aes))", .driver_name = "authenc-hmac-md5-cbc-aes-caam", @@ -2217,9 +2213,7 @@ static int __init caam_algapi_init(void) for (i = 0; i < ARRAY_SIZE(driver_algs); i++) { /* TODO: check if h/w supports alg */ struct caam_crypto_alg *t_alg; - bool done = false; -authencesn: t_alg = caam_alg_alloc(ctrldev, &driver_algs[i]); if (IS_ERR(t_alg)) { err = PTR_ERR(t_alg); @@ -2233,25 +2227,8 @@ authencesn: dev_warn(ctrldev, "%s alg registration failed\n", t_alg->crypto_alg.cra_driver_name); kfree(t_alg); - } else { + } else list_add_tail(&t_alg->entry, &priv->alg_list); - if (driver_algs[i].type == CRYPTO_ALG_TYPE_AEAD && - !memcmp(driver_algs[i].name, "authenc", 7) && - !done) { - char *name; - - name = driver_algs[i].name; - memmove(name + 10, name + 7, strlen(name) - 7); - memcpy(name + 7, "esn", 3); - - name = driver_algs[i].driver_name; - memmove(name + 10, name + 7, strlen(name) - 7); - memcpy(name + 7, "esn", 3); - - done = true; - goto authencesn; - } - } } if (!list_empty(&priv->alg_list)) dev_info(ctrldev, "%s algorithms registered in /proc/crypto\n", diff --git a/drivers/crypto/caam/compat.h b/drivers/crypto/caam/compat.h index cf15e7813801..762aeff626ac 100644 --- a/drivers/crypto/caam/compat.h +++ b/drivers/crypto/caam/compat.h @@ -23,7 +23,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From eda81bea894e5cd945e30f85b00546caf80fbecc Mon Sep 17 00:00:00 2001 From: Paul Bolle Date: Wed, 20 Mar 2013 09:44:17 +0100 Subject: usb: gadget: net2272: finally convert "CONFIG_USB_GADGET_NET2272_DMA" The Kconfig symbol USB_GADGET_NET2272_DMA was renamed to USB_NET2272_DMA in commit 193ab2a6070039e7ee2b9b9bebea754a7c52fd1b ("usb: gadget: allow multiple gadgets to be built"). That commit did not convert the only occurrence of the corresponding Kconfig macro. Convert that macro now. Signed-off-by: Paul Bolle Signed-off-by: Felipe Balbi --- drivers/usb/gadget/net2272.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index 17628337c6b0..32524b631959 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c @@ -59,7 +59,7 @@ static const char * const ep_name[] = { }; #define DMA_ADDR_INVALID (~(dma_addr_t)0) -#ifdef CONFIG_USB_GADGET_NET2272_DMA +#ifdef CONFIG_USB_NET2272_DMA /* * use_dma: the NET2272 can use an external DMA controller. * Note that since there is no generic DMA api, some functions, -- cgit v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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 v1.2.3 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